单链表练习
直接贴代码:
#pragma once
#include <stdio.h>
#include <stdlib.h>
/**
* 单链表练习
* -std=c99
*/
typedef int type;
struct SingleListNode {
type data;
struct SingleListNode *next;
};
struct SingleList {
unsigned int size;
struct SingleListNode *head;
};
/**
* 函数声明
*/
struct SingleList* SingleListCreate();
void SingleListPushBack(struct SingleList *list, type data);
void SingleListPushFront(struct SingleList *list, type data);
struct SingleListNode* SingleListPopBack(struct SingleList *list);
struct SingleListNode* SingleListPopFront(struct SingleList *list);
struct SingleListNode* SingleListAt(struct SingleList *list, unsigned int index);
void SingleListInsert(struct SingleList *list, unsigned int pos, type data);
void SingleListRemove(struct SingleList *list, unsigned int pos);
void SingleListReverse(struct SingleList *list);
type* SingleListToArray(struct SingleList *list);
struct SingleList* SingleListFromArray(type* array, unsigned int len);
struct SingleList* SingleListSub(struct SingleList *list, unsigned int bpos, unsigned int epos);
void SingleListErase(struct SingleList *list);
void SingleListPrintNode(unsigned int index, struct SingleListNode *node);
void SingleListPrintList(struct SingleList *list);
/**
* 创建并初始化一个链表
*/
struct SingleList* SingleListCreate() {
struct SingleList *list = (struct SingleList*) malloc(sizeof(struct SingleList));
list->head = NULL;
list->size = 0;
return list;
}
/**
* 尾部追加一个节点
*/
void SingleListPushBack(struct SingleList *list, type data) {
struct SingleListNode *node = (struct SingleListNode*)malloc(sizeof(struct SingleListNode));
node->next = NULL;
node->data = data;
if (list->head == NULL) {
list->head = node;
} else {
struct SingleListNode *temp = list->head;
while(temp->next != NULL) {
temp = temp->next;
}
temp->next = node;
}
++list->size;
}
/**
* 头部增加一个节点
*/
void SingleListPushFront(struct SingleList *list, type data) {
struct SingleListNode *node = (struct SingleListNode*)malloc(sizeof(struct SingleListNode));
node->next = list->head;
node->data = data;
list->head = node;
++list->size;
}
/**
* 尾部弹出一个节点,节点使用完后一定要free掉
*/
struct SingleListNode* SingleListPopBack(struct SingleList *list) {
if (list->head == NULL) {
return NULL;
}
struct SingleListNode *node = list->head;
if (node->next == NULL) {
list->head = NULL;
--list->size;
return node;
}
while (node->next->next != NULL) {
node = node->next;
}
struct SingleListNode *temp = node->next;
node->next = NULL;
--list->size;
temp->next = NULL;
return temp;
}
/**
* 头部弹出一个节点,节点使用完后一定要free掉
*/
struct SingleListNode* SingleListPopFront(struct SingleList *list) {
if (list->head == NULL) {
return NULL;
}
struct SingleListNode *node = list->head;
list->head = list->head->next;
--list->size;
node->next = NULL;
return node;
}
/**
* 按索引获取某个节点
*/
struct SingleListNode* SingleListAt(struct SingleList *list, unsigned int index) {
if (list->head == NULL || index >= list->size) {
printf("ERROR: index out of list! [%d > %d]\n", index, list->size);
return NULL;
}
struct SingleListNode *node = list->head;
for (unsigned int i = 0; i < index; i++) {
node = node->next;
}
return node;
}
/**
* 指定位置插入数据
* 思路:找到指定位置的前一个节点的后面加入节点
*/
void SingleListInsert(struct SingleList *list, unsigned int pos, type data) {
if (pos > list->size) {
printf("ERROR: index out of list! [%d > %d]\n", pos, list->size);
return;
}
if (pos == 0) {
SingleListPushFront(list, data);
return;
}
struct SingleListNode *temp = SingleListAt(list, pos - 1);
struct SingleListNode *node = (struct SingleListNode*)malloc(sizeof(struct SingleListNode));
node->data = data;
node->next = temp->next;
temp->next = node;
++list->size;
}
/**
* 移除指定位置的节点
* 思路:找到指定位置的前一个节点指向后一个节点
* TODO: 有BUG!
*/
void SingleListRemove(struct SingleList *list, unsigned int pos) {
if (pos > list->size) {
printf("ERROR: index out of list! [%d > %d]\n", pos, list->size);
return;
}
struct SingleListNode *node;
if (pos == 0) {
node = SingleListPopFront(list);
free(node);
return;
}
if (pos == list->size - 1) {
node = SingleListPopBack(list);
free(node);
return;
}
node = SingleListAt(list, pos - 1);
struct SingleListNode *temp = node->next;
temp->next = NULL;
free(temp);
node->next = node->next->next;
--list->size;
}
/**
* 反转链表
* 思路:头插法,新开一个临时链表,将节点从老链表中移除依次插入新链表的头部
*/
void SingleListReverse(struct SingleList *list) {
if (list->head == NULL || list->head->next == NULL) {
return;
}
struct SingleList *tempList = SingleListCreate();
struct SingleListNode *node = SingleListPopFront(list);
while(node != NULL) {
node->next = tempList->head;
tempList->head = node;
++tempList->size;
node = SingleListPopFront(list);
}
list->head = tempList->head;
list->size = tempList->size;
tempList->head = NULL;
free(tempList);
}
/**
* 链表转数组
* 数组用完记得free掉!
*/
type* SingleListToArray(struct SingleList *list) {
type *array = (type*)malloc(sizeof(type) * list->size);
struct SingleListNode *node = list->head;
for (unsigned int i = 0; i < list->size && node != NULL; i++) {
array[i] = node->data;
node = node->next;
}
return array;
}
/**
* 数组转链表
* 用完记得free掉!
*/
struct SingleList* SingleListFromArray(type* array, unsigned int len) {
if (array == NULL) {
return NULL;
}
struct SingleList *list = SingleListCreate();
for (unsigned int i = 0; i < len; i++) {
SingleListPushBack(list, array[i]);
}
return list;
}
/**
* 截取子链表
* 用完记得free掉!
* 前闭后开区间
*/
struct SingleList* SingleListSub(struct SingleList *list, unsigned int bpos, unsigned int epos) {
if (bpos > epos) {
unsigned int tempInt = bpos;
bpos = epos;
epos = tempInt;
}
if (epos >= list->size) {
printf("ERROR: index out of list! [%d > %d]\n", epos, list->size);
return NULL;
}
struct SingleList *subList = SingleListCreate();
struct SingleListNode *node = list->head;
for (unsigned int i = 0; i < bpos; i++) {
node = node->next;
}
for (unsigned int i = bpos; i < epos; i++) {
SingleListPushBack(subList, node->data);
node = node->next;
}
return subList;
}
/**
* 清空链表
*/
void SingleListErase(struct SingleList *list) {
while (list->head != NULL) {
struct SingleListNode *node = list->head;
list->head = list->head->next;
node->next = NULL;
free(node);
--list->size;
}
}
/**
* 调测用,打印节点
*/
void SingleListPrintNode(unsigned int index, struct SingleListNode *node) {
printf("%03d\taddr=%p\tnext=%p\tval=%d\n", index, node, node->next, node->data);
}
/**
* 调测用,打印链表
*/
void SingleListPrintList(struct SingleList *list) {
struct SingleListNode *temp = list->head;
for(unsigned int i = 0; i < list->size && temp != NULL; temp = temp->next, ++i) {
SingleListPrintNode(i, temp);
}
printf("list->size = %d\n", list->size);
}
void test() {
printf("--PushFront--------------\n");
struct SingleList *list = SingleListCreate();
for (int i = 10; i < 20; i++) {
SingleListPushFront(list, i);
}
SingleListPrintList(list);
printf("--PopFront---------------\n");
struct SingleListNode *node = NULL;
node = SingleListPopFront(list);
if (node != NULL) {
SingleListPrintNode(0, node);
free(node);
}
printf("--PopBack----------------\n");
node = SingleListPopBack(list);
if (node != NULL) {
SingleListPrintNode(0, node);
free(node);
}
printf("--At---------------------\n");
for (unsigned int i = 0; i < list->size; i++) {
SingleListPrintNode(i, SingleListAt(list, i));
}
printf("--Insert-----------------\n");
SingleListInsert(list, 0, 22);
SingleListInsert(list, 1, 23);
SingleListInsert(list, list->size, 24);
SingleListPrintList(list);
printf("--Remove-----------------\n");
SingleListRemove(list, 0);
//SingleListRemove(list, 2);
SingleListPrintList(list);
printf("--Reverse----------------\n");
SingleListReverse(list);
SingleListPrintList(list);
printf("--Sub--------------------\n");
struct SingleList *subList = SingleListSub(list, 4, 18);
if (subList != NULL) {
SingleListPrintList(subList);
SingleListErase(subList);
free(subList);
}
printf("--ToArray----------------\n");
type *arr = SingleListToArray(list);
for (unsigned int i = 0; i < list->size; i++) {
printf("%03d\t%d\n", i, arr[i]);
}
free(arr);
printf("--FromArray--------------\n");
type *arr2 = (type*)malloc(sizeof(type) * 4);
for (int i = 0; i < 4; i++) {
arr2[i] = 30 + i;
}
struct SingleList *newList = SingleListFromArray(arr2, 4);
SingleListPrintList(newList);
SingleListErase(newList);
free(newList);
printf("--Erase------------------\n");
SingleListErase(list);
SingleListPrintList(list);
}
©raveh.net