顺序表和链表是基本的数据结构,也是最简单但又很重要的数据结构。
一.顺序表
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; }
以上就是本人在学习过程中的一些经验总结。当然,本人能力有限,难免会有纰漏,希望大家可以指正。