手把手写数据结构之单向链表操作(一)
/**********************头文件数据封装及函数声明****************/ #ifndef _S_LIST_H #define _S_LIST_H #include <stdio.h> #include <stdlib.h> #define PRINT printf("LINE: %d\n", __LINE__); /*单链表的实现可以各有不同,只要该实现,符合链表的定义即可。 *单链表最重要的数据结构是元素结点, *最重要的操作是插入结点,删除结点和遍历。 *其它的操作基本上是这3个操作的组合,依据具体的要求而定。 */ /******************************************* *单向链表结点信息 * *数据域: 可以是普通类型,也可以是封装类型 *指针域: next指针 * *********************************************/ typedef struct node { int num; //数据域 struct node *next; //指针域 }NODE; /******************************************* *单向链表信息 * *链表的属性信息: 链表的作用描述,链表当前节点个数等等 *指针信息: 一般必须有表头指针,也可以有为结点指针 * *********************************************/ typedef struct list_info { int max; //结点个数 NODE *head; //头结点指针 }LIST_INFO; /******************************************** *Des: 创建链表 *Ret: 成功返回0, 失败返回-1; *********************************************/ int Create_List(LIST_INFO **plist); /******************************************** *Des: 判断链表是否为空 *Ret: 真: 1, 假: 0 *********************************************/ int Is_Empty_List(const LIST_INFO *plist); /******************************************** *Des: 添加新的数据节点到表头 *Ret: 成功返回0, 失败返回-1; *********************************************/ int AddtoList_Head(LIST_INFO *plist, const int num); /******************************************** *Des: 添加新的数据结点到表尾 *Ret: 成功返回0, 失败返回-1; *********************************************/ int AddtoList_Tail(LIST_INFO *plist, const int num); /******************************************** *Des: 查找某个结点是否存在,存在返回前一个结点 *Ret: NULL:不存在或出错,(NODE *)1:该节点为头结点 *********************************************/ NODE * Find_Node(const LIST_INFO *plist, const int num); /******************************************** *Des: 获取第m结点的数据 *Ret: 成功返回0,失败返回-1 *********************************************/ int Get_Node_Info(const LIST_INFO *plist, int *num, const int M); /******************************************** *Des: 将新的数据num插入到数据域为dest_num结点前面 *Ret: 成功返回0,返回-1; *********************************************/ int Insert_num_to_Node(LIST_INFO *plist, const int num, const int dest_num); /******************************************** *将新的数据结点添加到第m个结点后 *成功返回0,返回-1; *********************************************/ int Add_num_to_M(LIST_INFO *plist, const int m, const int num); /******************************************** *Des: 删除第一个数据与为num的结点 *Ret: 成功返回0,返回-1; *********************************************/ int Delete_num_from(LIST_INFO *plist, const int num); /******************************************** *Des: 遍历链表 *Ret: 成功返回0,返回-1; *********************************************/ int Traverse_List(const LIST_INFO *plist); /******************************************** *Des: 将链表所有节点排序(按数据从小到大) *Ret: 成功返回0,返回-1; *********************************************/ int Order_List(LIST_INFO *plist); /******************************************** *Des: 清空链表 *Ret: 成功返回0,返回-1; *********************************************/ int Empty_List(LIST_INFO *plist); /******************************************** *Des: 将链表逆序 *Ret: 成功返回0,返回-1; *********************************************/ int Reverse_List(LIST_INFO *plist); /******************************************** *Des: 获取链表结点个数 *Ret: 成功返回结点个数,失败返回-1; *********************************************/ int Get_count_Node(const LIST_INFO *plist); /******************************************** *Des: 销毁链表 *Ret: 成功返回0,失败返回-1; *********************************************/ int Destory_List(LIST_INFO **plist); /******************************************** *Des: 顺序表结点插入 (已经按从小到大排好序的链表) *Ret: 成功返回0,失败返回-1; *********************************************/ int Order_Insert__Node(LIST_INFO * plist, const int num); #endif /***************************函数定义的实现********************/ #include "s_list.h" /******************************************** *Des: 创建结点并填充结点信息 *Ret: 成功返回结点, 失败返回NULL; *********************************************/ static NODE *__Create_Node__(int num) { NODE *new_node = (NODE *)malloc(sizeof(NODE)); if(NULL == new_node) { perror("Malloc new node"); return NULL; } new_node->num = num; new_node->next = NULL; return new_node; } /******************************************** *Des: 创建链表 *Ret: 成功返回0, 失败返回-1; *********************************************/ int Create_List(LIST_INFO **plist) { if(NULL == plist) return -1; *plist = (LIST_INFO *)malloc(sizeof(LIST_INFO)); if(NULL == *plist) { perror("List malloc"); return -1; } (*plist)->head = NULL; (*plist)->max = 0; return 0; } /******************************************** *Des: 判断链表是否为空 *Ret: 真: 1, 假: 0 *********************************************/ int Is_Empty_List(const LIST_INFO *plist) { return (NULL == plist->head) ? 1: 0; } /******************************************** *Des: 添加新的数据节点到表头 *Ret: 成功返回0, 失败返回-1; *********************************************/ int AddtoList_Head(LIST_INFO *plist, const int num) { NODE *new_node = __Create_Node__(num); if(NULL == new_node) return -1; new_node->next = plist->head; plist->head = new_node; plist->max++; return 0; } /******************************************** *Des: 添加新的数据结点到表尾 *Ret: 成功返回0, 失败返回-1; *********************************************/ int AddtoList_Tail(LIST_INFO *plist, const int num) { NODE *pnode = plist->head, *tmpnode = NULL; NODE *new_node = __Create_Node__(num); if(NULL == new_node) return -1; //链表为空 if(Is_Empty_List(plist)) { plist->head = new_node; } else { while(NULL != pnode->next) { pnode = pnode->next; } pnode->next = new_node; } plist->max++; return 0; } /******************************************** *Des: 查找某个结点是否存在,存在返回前一个结点 *Ret: NULL:不存在或出错,(NODE *)1:该节点为头结点 *********************************************/ NODE * Find_Node(const LIST_INFO *plist, const int num) { NODE *pre_node = (NODE *)1; NODE *tmpnode = NULL, *pnode = plist->head; while(NULL != pnode) { if(pnode->num == num) return pre_node; pre_node = pnode; pnode = pnode->next; } return NULL; } /******************************************** *Des: 获取第m结点的数据 *Ret: 成功返回0,失败返回-1 *********************************************/ int Get_Node_Info(const LIST_INFO *plist, int *num, const int M) { int idx = 0; if(M > Get_count_Node(plist) || M <= 0) { printf("Invalid arg!\n"); return -1; } NODE *pnode = plist->head; while(NULL != pnode) { idx++; if(idx == M) break; pnode = pnode->next; } *num = pnode->num; return 0; } /******************************************** *将新的数据结点添加到第m个结点后 *成功返回0,返回-1; *********************************************/ int Add_num_to_M(LIST_INFO *plist, const int m, const int num) { int idx = 0; if(m > Get_count_Node(plist) || m <= 0) { printf("Invalid arg!\n"); return -1; } NODE *new_node = __Create_Node__(num); if(NULL == new_node) { return -1; } NODE *pnode = plist->head; while(NULL != pnode) { idx++; if(idx == m) break; pnode = pnode->next; } new_node->next = pnode->next; pnode->next = new_node; plist->max++; return 0; } /******************************************** *Des: 将新的数据num插入到数据域为dest_num结点前面 *Ret: 成功返回0,返回-1; *********************************************/ int Insert_num_to_Node(LIST_INFO *plist, const int num, const int dest_num) { //查找dest_num结点 NODE *pre_node = Find_Node(plist, dest_num); if(NULL == pre_node) { printf("No such node!\n"); return -1; } //创建结点 NODE *new_node = __Create_Node__(num); if(NULL == new_node) { return -1; } //若插入到表头 if(pre_node == (NODE *)1) { new_node->next = plist->head; plist->head = new_node; } else//插入到其他位置 { new_node->next = pre_node->next; pre_node->next = new_node; } plist->max++; return 0; } /******************************************** *Des: 删除第一个数据与为num的结点 *Ret: 成功返回0,返回-1; *********************************************/ int Delete_num_from(LIST_INFO *plist, const int num) { NODE *fnode = NULL; NODE *prev_node = Find_Node(plist, num); if(NULL == prev_node) { printf("Have no such Node!\n"); return -1; } if((NODE *)1 == prev_node) { fnode = plist->head; plist->head = fnode->next; } else { fnode = prev_node->next; prev_node->next = fnode->next; } free(fnode); plist->max--; return 0; } /******************************************** *Des: 遍历链表 *Ret: 成功返回0,返回-1; *********************************************/ int Traverse_List(const LIST_INFO *plist) { //函数入口检测 if(NULL == plist) { printf("Invalid arg!\n"); return -1; } NODE *pnode = plist->head; if(Is_Empty_List(plist)) { printf("The List is empty!\n"); return -1; } printf("The List node count: %d\n", Get_count_Node(plist)); while(NULL != pnode) { printf("%-5d", pnode->num); pnode = pnode->next; } printf("\n\n"); return 0; } /******************************************** *Des: 将链表所有节点排序(按数据从小到大) *Ret: 成功返回0,返回-1; (没有想出更好方法) *********************************************/ int Order_List(LIST_INFO *plist) { NODE *pnode = plist->head->next, *head = plist->head; head->next = NULL; NODE *tmpnode = NULL, *pre_p = NULL, *tmp = NULL; while(pnode != NULL) { tmp = pnode->next; tmpnode = head; if(pnode->num <= head->num) { pnode->next = head; head = pnode; } else { pre_p = head; tmpnode = head->next; while(tmpnode != NULL) { if(pnode->num <= tmpnode->num) { break; } pre_p = tmpnode; tmpnode = tmpnode->next; } pre_p->next = pnode; pnode->next = tmpnode; } pnode = tmp; } plist->head = head; return 0; } /******************************************** *Des: 清空链表 *Ret: 成功返回0,返回-1; *********************************************/ int Empty_List(LIST_INFO *plist) { if(NULL == plist) { printf("Invalid arg!\n"); return -1; } NODE *fnode = NULL, *pnode = plist->head; while(NULL != pnode) { fnode = pnode; pnode = pnode->next; free(fnode); } plist->head = NULL; plist->max = 0; return 0; } /******************************************** *Des: 将链表逆序 *Ret: 成功返回0,返回-1; *********************************************/ int Reverse_List(LIST_INFO *plist) { if(NULL == plist)//函数入口检测 { printf("Invalid arg!\n"); return -1; } NODE *head = NULL, *tmpnode = NULL, *pnode = plist->head; while(NULL != pnode) { tmpnode = pnode; pnode = pnode->next; tmpnode->next = head; head = tmpnode; } plist->head = head; return 0; } /******************************************** *Des: 顺序表结点插入 (已经按从小到大排好序的链表) *Ret: 成功返回0,失败返回-1; *********************************************/ int Order_Insert__Node(LIST_INFO * plist, const int num) { if(NULL == plist)//函数入口检测 { printf("Invalid arg!\n"); return -1; } NODE *pnode = NULL, *tmpnode = NULL; NODE *new_node = __Create_Node__(num);//创建新的结点 if(NULL == new_node) return -1; pnode = plist->head; //链表为空 if(plist->head == NULL) { plist->head = new_node; } //第一个结点就大于num else if(plist->head->num > num) { new_node->next = plist->head; plist->head = new_node; } else { tmpnode = plist->head; pnode = plist->head->next; while(NULL != pnode) { if(pnode->num > num) break; tmpnode = pnode; pnode = pnode->next; } new_node->next = tmpnode->next; tmpnode->next = new_node; } plist->max++; return 0; } /******************************************** *Des: 获取链表结点个数 *Ret: 成功返回结点个数,失败返回-1; *********************************************/ int Get_count_Node(const LIST_INFO *plist) { return plist->max; } /******************************************** *Des: 销毁链表 *Ret: 成功返回0,失败返回-1; *********************************************/ int Destory_List(LIST_INFO **plist) { if(Empty_List(*plist) < 0) return -1; free(*plist); *plist = NULL; return 0; }