/**********************頭文件數據封裝及函數聲明****************/ #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; }