順序表和鏈表是基本的數據結構,也是最簡單但又很重要的數據結構。
一.順序表
1.直接給數組大小的情況
typedef int DataType; typedef struct SeqList { Datatype array[MAXSIZE]; size_t size; }SeqList
2.需要擴容的
typedef int Datatype; typedef struct SeqList_D { Datatype *array; //數據塊指針 size_t size; //有效數據 Datatype capacity; //容量 }SeqList_D;
分析:
1).兩種情況,第二種明顯優於第一種,不會存在內存浪費的情況。在計算機可用內存中,第二種可以無上限的擴容,而第一種會受到MAXSIZE的限制。
2).兩種情況的初始化有差異。直接給數組大小的將有效數據置爲0就好,在每次插入數據的時候只需要判斷有效數據和數組大小;擴容的需要動態開闢內存,並且在插入數據的時候要判斷有效數據和容量的大小。
3).需要提的是,不管是增刪改查,都需要將定義的結構的變量的地址傳給操作函數。
二.單向鏈表
typedef int DataType; typedef struct ListNode { DataType data; //存放的數據 struct ListNode* next; //指向下一個節點的指針 }ListNode;
分析:單向鏈表這裏需要注意鏈表爲空,只有一個結點和有多個節點的情況。
1).單向鏈表不需要初始化,直接進行插入操作就可以了。
2).在增刪改查的操作中都是進行穿地址的操作來實現,在函數的形參中可以用二級指針來接收,也可以用使用c++中引用的概念。
3).寫函數需要注意的東西就不再多說,原來的博客裏面有。
4).測試用例很重要。
5).自己的一個小程序讓大家看看
頭文件
#ifndef __LinkedList_12_31_H__ #define __LinkedList_12_31_H__ #include<assert.h> #include<stdlib.h> typedef int Datatype; typedef struct ListNode { Datatype data; struct ListNode *next; }ListNode; //沒有節點,一個節點,多個節點 ListNode* _BuyNode(Datatype x); void print(ListNode *pHead); //void Pushback(ListNode **pHead,Datatype x); void Pushback(ListNode*& pHead,Datatype x); void Popback(ListNode*& pHead); void pushFront(ListNode*& pHead,Datatype x); void PopFront(ListNode*& pHead); ListNode* Find(ListNode* phead, Datatype x); void Insert(ListNode* pos, Datatype x); void Erase(ListNode*pHead, ListNode* pos); #endif //__LinkedList_12_31_H__
實現函數
#include<stdio.h> #include"LinkedList_12_31.h" ListNode* _BuyNode(Datatype x) { ListNode *tmp = (ListNode*)malloc(sizeof(ListNode)); if (tmp != NULL) { tmp->data = x; tmp->next = NULL; } return tmp; } // //void Pushback(ListNode **pHead, Datatype x) //{ // assert(pHead); // if (*pHead == NULL) // { // *pHead = _BuyNode(x); // } // else // { // ListNode* tail = *pHead; // while (tail->next != NULL) // { // tail = tail->next; // } // tail->next = _BuyNode(x); // } //} void Pushback(ListNode*& pHead, Datatype x) { if (pHead == NULL) { pHead = _BuyNode(x); } else { ListNode*tail = pHead; while (tail->next != NULL) { tail = tail->next; } tail->next = _BuyNode(x); } } void Popback(ListNode*& pHead) { if (pHead == NULL) { printf("empty\n"); return; } else if (pHead->next == NULL) { free(pHead); pHead = NULL; } else { ListNode* tail = pHead; ListNode* cur = NULL; while (tail->next) { cur = tail; tail = tail->next; } free(tail); cur->next = NULL; } } void pushFront(ListNode*& pHead, Datatype x) { if (pHead == NULL) { pHead = _BuyNode(x); } else { ListNode*tmp = _BuyNode(x); tmp->next = pHead; pHead = tmp; } } void PopFront(ListNode*& pHead) { if (pHead == NULL) { printf("empty LinkedList\n"); return; } else if (pHead->next == NULL) { free(pHead); pHead = NULL; } else { ListNode* tmp = pHead; pHead = pHead->next; free(tmp); } } ListNode* Find(ListNode* pHead, Datatype x) { assert(pHead);//沒有節點的時候 ListNode* tail = pHead; while (tail->next)//多個節點的時候 { if (tail->data == x) { return tail; } tail = tail->next; } if (tail->next == NULL)//一個節點的時候 { return tail; } return NULL; } void Insert(ListNode* pos, Datatype x) { assert(pos); ListNode*tmp = _BuyNode(x); ListNode*cur = pos->next; pos->next = tmp; tmp->next = cur; } void Erase(ListNode*pHead, ListNode* pos) { assert(pos); if (pos->next == NULL) { free(pos); // } else { ListNode*cur = NULL; ListNode*tail = pos; while (pHead->data != tail->data) { cur = pHead; pHead = pHead->next; } ListNode*tmp = pos->next; cur->next = tmp; free(pos); } } void print(ListNode *pHead) { //assert(pHead); ListNode* cur = pHead; while (cur) //不可以 寫成while(cur->next); 會少打印一個節點 { printf("%d->", cur->data); cur = cur->next; } printf("NULL\n"); }
測試用例
#include<stdio.h> #include"LinkedList_12_31.h" // //void Test1() //{ // ListNode* list = NULL; // Pushback(&list,1); // Pushback(&list, 2); // Pushback(&list, 3); // Pushback(&list, 4); // print(list); //} //Pushback()/Popback() void Test2() { ListNode* list = NULL; Pushback(list, 1); Pushback(list, 2); Pushback(list, 3); Pushback(list, 4); Pushback(list, 5); print(list); Popback(list); Popback(list); Popback(list); Popback(list); Popback(list); Popback(list); print(list); } void Test3() { ListNode* list = NULL; pushFront(list, 5); pushFront(list, 4); pushFront(list, 3); pushFront(list, 2); pushFront(list, 1); print(list); PopFront(list); PopFront(list); PopFront(list); PopFront(list); PopFront(list); PopFront(list); print(list); } void Test4() { ListNode* list = NULL; pushFront(list, 5); pushFront(list, 4); pushFront(list, 3); pushFront(list, 2); pushFront(list, 1); print(list); //ListNode*tmp = Find(list, 2); //ListNode*tmp = Find(NULL, 2); ListNode*tmp = Find(list, 5); printf("%d->", tmp->data); } void Test5() { ListNode* list = NULL; pushFront(list, 5); pushFront(list, 4); pushFront(list, 3); pushFront(list, 2); pushFront(list, 1); print(list); ListNode*tmp = Find(list, 2); Insert(tmp, 2); print(list); } void Test6() { ListNode* list = NULL; pushFront(list, 5); pushFront(list, 4); pushFront(list, 3); pushFront(list, 2); pushFront(list, 1); print(list); ListNode*tmp = Find(list, 2); Insert(tmp, 2); print(list); Erase(list, tmp); print(list); } int main() { Test6(); system("pause"); return 0; }
以上就是本人在學習過程中的一些經驗總結。當然,本人能力有限,難免會有紕漏,希望大家可以指正。