赞
踩
SeqList.h
- #pragma once
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #include<errno.h>
- #include<assert.h>
- typedef int SLDataType;
- // 顺序表的动态存储
- typedef struct SeqList
- {
- SLDataType* array; // 指向动态开辟的数组
- size_t size; // 有效数据个数
- size_t capicity; // 容量空间的大小
- }SeqList;
- SeqList SL;
- // 基本增删查改接口
- // 顺序表初始化
- void SeqListInit(SeqList* psl);
-
- // 检查空间,如果满了,进行增容
- void CheckCapacity(SeqList* psl);
-
- // 顺序表尾插
- void SeqListPushBack(SeqList* psl, SLDataType x);
-
- // 顺序表尾删
- void SeqListPopBack(SeqList* psl);
-
- // 顺序表头插
- void SeqListPushFront(SeqList* psl, SLDataType x);
-
- // 顺序表头删
- void SeqListPopFront(SeqList* psl);
-
- // 顺序表查找
- int SeqListFind(SeqList* psl, SLDataType x);
-
- // 顺序表在pos位置插入x
- void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
-
- // 顺序表删除pos位置的值
- void SeqListErase(SeqList* psl, size_t pos);
-
- // 顺序表销毁
- void SeqListDestory(SeqList* psl);
-
- // 顺序表打印
- void SeqListPrint(SeqList* psl);
-
- //顺序表修改
- void SLModify(SeqList* psl, size_t pos, SLDataType x);

SeqList.c
- #define _CRT_SECURE_NO_WARNINGS
-
- #include "SeqList.h"
-
- // 顺序表初始化
- void SeqListInit(SeqList* psl) {
- assert(psl);
-
- psl->capicity = 0;
- psl->size = 0;
- psl->array = NULL;
-
-
- }
-
- //顺序表打印
- void SeqListPrint(SeqList* psl) {
- assert(psl);
- for (int i = 0; i < psl->size; i++) {
- printf("%d ", psl->array[i]);
- }
-
- }
-
- // 顺序表头插
- void SeqListPushFront(SeqList* psl, SLDataType x) {
- assert(psl);
-
- //检查空间是否足够
- CheckCapacity(&psl);
- int temp_size = psl->size;
- while (temp_size > 0) {
-
- psl->array[temp_size] = psl->array[temp_size-1];
- temp_size--;
-
- }
- psl->array[0] = x;
- psl->size++;
-
- }
-
- // 顺序表尾插
- void SeqListPushBack(SeqList* psl, SLDataType x) {
- assert(psl);
-
- //检查空间是否足够
- CheckCapacity(&psl);
-
- psl->array[psl->size] = x;
- psl->size++;
-
- }
-
- // 顺序表销毁
- void SeqListDestory(SeqList* psl) {
-
- assert(psl);
- free(psl->array);
- psl->array = NULL;
- psl->capicity = 0;
- psl->size = 0;
-
- }
- // 检查空间,如果满了,进行增容
- void CheckCapacity(SeqList** psl) {
-
- if ((*psl)->capicity == 0) {
- SLDataType* temp = NULL;
- (*psl)->capicity = 4 * sizeof(SLDataType);
- temp = (SLDataType)malloc((*psl)->capicity);
- if (temp == NULL) {
- perror(CheckCapacity);
- return 0;
- }
- (*psl)->array = temp;
-
- return;
- }
-
- if ((*psl)->capicity <= (*psl)->size*sizeof(SLDataType)) {
- (*psl)->capicity *= 2;
- SLDataType* temp = NULL;
- //检查开辟是否成功
- temp = (SLDataType)realloc((*psl)->array,(*psl)->capicity);
-
- if (temp == NULL) {
- perror(CheckCapacity);
- return 0;
- }
- (*psl)->array = temp;
- }
-
- }
-
- // 顺序表尾删
- void SeqListPopBack(SeqList* psl) {
-
- assert(psl);
-
- psl->size--;
- }
-
- // 顺序表头删
- void SeqListPopFront(SeqList* psl) {
- assert(psl);
-
- int temp_size = 1;
- while (temp_size <= psl->size) {
-
- psl->array[temp_size-1] = psl->array[temp_size];
- temp_size++;
-
- }
- psl->size--;
-
- }
- // 顺序表查找
- int SeqListFind(SeqList* psl, SLDataType x) {
- assert(psl);
- //找到返回下标
- for (int i = 0; i < psl->size; i++) {
- if (psl->array[i] == x) {
-
- return i;
- }
- }
- //没找到返回-1;
- return -1;
- }
-
-
- // 顺序表删除pos位置的值
- void SeqListErase(SeqList* psl, size_t pos) {
-
- assert(psl);
- assert(pos < psl->size);
- if (pos >= psl->size) {
- printf("删除超出范围限制");
- return ;
- }
-
- while (pos < psl->size) {
- psl->array[pos] = psl->array[pos + 1];
- pos++;
- }
- psl->size--;
- }
-
- // 顺序表在pos位置插入x
- void SeqListInsert(SeqList* psl, size_t pos, SLDataType x) {
-
- assert(psl);
- assert(pos <= psl->size);
-
- CheckCapacity(&psl);
-
- int temp = psl->size;
- while (temp > pos) {
- psl->array[temp] = psl->array[temp - 1];
- temp--;
- }
- psl->array[pos] = x;
- psl->size++;
- }
-
- //修改
- void SLModify(SeqList* psl, size_t pos, SLDataType x) {
-
- assert(psl);
- assert(pos < psl->size);
-
- psl->array[pos] = x;
-
- }

单链表.h
- #pragma once
- #include<stdio.h>
- #include<assert.h>
- #include<stdlib.h>
-
- typedef int SLTDateType;
- typedef struct SListNode
- {
- SLTDateType data;
- struct SListNode* next;
- }SListNode;
- // 动态申请一个结点
- SListNode* BuySListNode(SLTDateType x);
- // 单链表打印
- void SListPrint(SListNode* plist);
- // 单链表尾插
- void SListPushBack(SListNode** pplist, SLTDateType x);
- // 单链表的头插
- void SListPushFront(SListNode** pplist, SLTDateType x);
- // 单链表的尾删
- void SListPopBack(SListNode** pplist);
- // 单链表头删
- void SListPopFront(SListNode** pplist);
- // 单链表查找
- SListNode* SListFind(SListNode* plist, SLTDateType x);
- // 单链表在pos位置之后插入x
- // 分析思考为什么不在pos位置之前插入?
- void SListInsertAfter(SListNode* pos, SLTDateType x);
- // 单链表 之前插入(难)
- void SListInsertBefore(SListNode* pos, SLTDateType x);
- // 单链表删除pos位置之后的值
- // 分析思考为什么不删除pos位置?
- void SListEraseAfter(SListNode* pos);
- // 单链表销毁
- void SLlistDestory(SListNode* phead);
- //单链表删除当前位置
- void SListErase(SListNode* pos);

单链表.c
- #define _CRT_SECURE_NO_WARNINGS
- #include"单链表.h"
-
- SListNode* BuySListNode(SLTDateType x) {
-
- SListNode* temp = (SListNode*)malloc(sizeof(SListNode));
-
- if (temp == NULL) {
- perror("malloc fail");
- exit(-1);
- }
- SListNode* newnode = temp;
- temp = NULL;
-
- newnode->data = x;
- newnode->next = NULL;
-
- return newnode;
- }
-
- // 单链表打印
- void SListPrint(SListNode* phead) {
-
- SListNode* cur = phead;
-
- while (cur) {
- printf("%d->", cur->data);
- cur = cur->next;
- }
- printf("NULL\n");
-
- }
-
- // 单链表的头插
- void SListPushFront(SListNode** pphead, SLTDateType x) { //改变一级指针就需要一级指针的地址,所以传入二级指针
- assert(pphead);
- SListNode* newnode = BuySListNode(x);
-
- newnode->next = *pphead;
- *pphead = newnode;
-
- }
-
- // 单链表尾插
- void SListPushBack(SListNode** pphead, SLTDateType x) {
- assert(pphead);
- //单链表不为空
- if (* pphead == NULL ) {
- SListNode* next = BuySListNode(x);
- *pphead = next;
-
-
- }//单链表为空
- else {
- SListNode* cur = *pphead;
- while (cur->next != NULL) {
- cur = cur->next;
- }
-
- SListNode* next = BuySListNode(x);
- cur->next = next;
- }
-
- }
- // 单链表头删
- void SListPopFront(SListNode** pphead) {
-
- assert(pphead);
- if (*pphead == NULL) {
- return;
- }
- SListNode* del = *pphead;
- *pphead = (*pphead)->next;
- free(del);
- del = NULL;
-
- }
-
- // 单链表的尾删
- void SListPopBack(SListNode** pphead) {
-
- assert(pphead);
- if (*pphead == NULL) {
- return;
- }
- if ((*pphead)->next == NULL) {
- free(*pphead);
- *pphead = NULL;
- return;
- }
- SListNode* cur = *pphead;
-
- while (cur->next->next != NULL) {
- cur = cur->next;
- }
- free(cur->next);
- cur->next = NULL;
-
-
- }
- // 单链表查找
- SListNode* SListFind(SListNode* pphead, SLTDateType x) {
-
- assert(pphead);
- SListNode* cur = pphead;
-
- while (cur) {
- if (x == cur->data) {
- printf("找到了\n");
- return cur;
- }
- else {
- cur = cur->next;
- }
-
- }
- return NULL;
-
- }
-
-
- //单链表在某位置之后插入
- void SListInsertAfter(SListNode** pphead,SListNode* pos, SLTDateType x) {
-
- assert(pphead);
-
- if (*pphead == NULL) {
- SListPushFront(pphead, x);
- return;
- }
-
- SListNode* newcode = BuySListNode(x);
- newcode->next = pos->next;//注意这两行的顺序
- pos->next = newcode;
-
- }
- // 单链表 之前插入(难)
- void SListInsertBefore(SListNode** pphead, SListNode* pos, SLTDateType x) {
-
- assert(pos);
- assert(pphead);
-
- if (*pphead == NULL) {
- SListPushFront(pphead, x);
- return;
- }
-
- //方法一:找到前一项的next
- SListNode* cur = *pphead;
- if (pos == pphead) {
- SListPushFront(pphead, x);
- return;
- }
- while (cur->next != pos) {
-
- cur = cur->next;
-
- //找不到,说明pos传错了
- assert(cur);
- }
- SListNode* newcode = BuySListNode(x);
- newcode->next = pos;
- cur->next = newcode;
- //方法二 顺序法交换
-
- //SListNode* newcode = BuySListNode(pos->data);
- //pos->data = x;
-
-
- }
- // 单链表删除pos位置之后的值
- // 分析思考为什么不删除pos位置?
- void SListEraseAfter(SListNode** pphead, SListNode* pos) {
-
- assert(pphead);
- assert(pos);
-
- if (pos->next == NULL) {
- SListPopBack(pphead);
- return;
- }
- SListNode* cur = pos->next;
- pos->next = pos->next->next;
-
- free(cur);
- }
-
-
- //单链表删除当前位置
- void SListErase(SListNode** pphead, SListNode* pos) {
- assert(pphead && pos);
-
- if (pos == *pphead) {
- SListPopFront(pphead);
- return;
- }
-
- SListNode* cur = pos->next->next;
- pos->data = pos->next->data;
- free(pos->next);
- pos->next = cur;
-
- }
-
-
- // 单链表销毁
- void SLlistDestory(SListNode** pphead) {
-
- assert(pphead);
- SListNode* cur = pphead;
- SListNode* next = pphead;
- while (cur) {
- next = cur->next;
- free(cur);
- cur = next;
- }
-
- pphead = NULL;
-
- }
-

List.h
- #pragma once
- #include<stdio.h>
- #include<assert.h>
- #include<stdlib.h>
-
- typedef int LTDataType;
- typedef struct ListNode
- {
- LTDataType _data;
- struct ListNode* next;
- struct ListNode* prev;
- }ListNode;
- // 创建返回链表的头结点.
- ListNode* ListCreate();
- //双向链表创造一个新节点
- ListNode* ListBuyNode(LTDataType x);
- // 双向链表打印
- void ListPrint(ListNode* plist);
- // 双向链表尾插
- void ListPushBack(ListNode* plist, LTDataType x);
- // 双向链表头插
- void ListPushFront(ListNode* plist, LTDataType x);
- // 双向链表尾删
- void ListPopBack(ListNode* plist);
- // 双向链表头删
- void ListPopFront(ListNode * plist);
- // 双向链表查找
- ListNode* ListFind(ListNode* plist, LTDataType x);
- // 双向链表在pos的前面进行插入
- void ListInsert(ListNode* pos, LTDataType x);
- // 双向链表删除pos位置的结点
- void ListErase(ListNode* pos);
- // 双向链表销毁
- void ListDestory(ListNode* plist);
-
-
-

List.c
- #define _CRT_SECURE_NO_WARNINGS
- #include"List.h"
-
- // 创建返回链表的头结点.
- ListNode* ListCreate() {
- ListNode* ListGuard = (ListNode*)malloc(sizeof(ListNode));
- if (ListGuard == NULL) {
- perror("ListGuard malloc fai");
- exit(-1);
- }
- ListGuard->next = ListGuard;
- ListGuard->prev = ListGuard;
- return ListGuard;
- }
-
- // 双向链表打印
- void ListPrint(ListNode* plist) {
- assert(plist);
- ListNode* head = plist;
- ListNode* cur = head->next;
-
- printf("head<=>");
- while (cur != head) {
- printf("%d<=>", cur->_data);
- cur = cur->next;
- }
- printf("\n");
- }
- //双向链表创造一个新节点
- ListNode* ListBuyNode(LTDataType x) {
- ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
- if (newNode == NULL) {
- perror("newNode malloc fail");
- exit(-1);
- }
- newNode->next = NULL;
- newNode->prev = NULL;
- newNode->_data = x;
- return newNode;
- }
- // 双向链表尾插
- void ListPushBack(ListNode* plist, LTDataType x) {
- assert(plist);
- ListNode* tail = plist->prev;
-
- ListNode* newNode = ListBuyNode(x);
- //节点四步走 注意语句顺序!
- newNode->next = plist;
- plist->prev = newNode;
- tail->next = newNode;
- newNode->prev = tail;
-
- }
- // 双向链表头插
- void ListPushFront(ListNode* plist, LTDataType x) {
- assert(plist);
- ListNode* first = plist->next;
-
- ListNode* newNode = ListBuyNode(x);
- //节点四步走 注意语句顺序!
- first->prev = newNode;
- newNode->next = first;
- plist->next = newNode;
- newNode->prev = plist;
-
- }
- //检查双向列表是否为空
- int CheckList(ListNode* plist) {
- assert(plist);
- //返回“真”为空 返回"假"为非空;
- return plist->next == plist->prev;
- }
- // 双向链表尾删
- void ListPopBack(ListNode* plist) {
- assert(plist);
- assert(!CheckList(plist));
- ListNode* tail = plist->prev;
-
- //节点链接
- tail->prev->next = plist;
- plist->prev = tail->prev;
- //释放
- free(tail);
- }
- // 双向链表头删
- void ListPopFront(ListNode* plist) {
- assert(plist);
- assert(!CheckList(plist));
- ListNode* first = plist->next;
-
- //节点链接
- plist->next = first->next;
- first->next->prev = plist;
-
- //释放
- free(first);
- }
- // 双向链表查找
- ListNode* ListFind(ListNode* plist, LTDataType x) {
- assert(plist);
- if (CheckList(plist)) {
- printf("链表为NULL,无法查找有效数据\n");
- exit(-1);
- }
- ListNode* cur = plist->next;
- while (cur != plist) {
- if (cur->_data == x) {
- printf("找到啦\n");
- return cur;
- }
- cur = cur->next;
- }
- return NULL;
- }
- // 双向链表在pos的前面进行插入
- void ListInsert(ListNode* pos, LTDataType x) {
- assert(pos);
- ListNode* first = pos->prev;
- ListNode* second = pos;
- ListNode* newNode = ListBuyNode(x);
-
- newNode->next = second;
- second->prev = newNode;
- first->next = newNode;
- newNode->prev = first;
-
- }
- // 双向链表删除pos位置的结点
- void ListErase(ListNode* pos) {
- assert(pos);
- ListNode* first = pos->prev;
- ListNode* del = pos;
- ListNode* second = pos->next;
-
- first->next = second;
- second->prev = first;
- free(del);
- }
- // 双向链表销毁
- void ListDestory(ListNode* plist) {
- assert(plist);
- ListNode* cur = plist->next;
- ListNode* next = NULL;
- plist->next = NULL;
- while (cur != NULL) {
- next = cur->next;
- free(cur);
- cur = next;
- }
- printf("销毁成功\n");
- }

顺序表
链表
顺序表优点:1.尾插、尾删效率高。2.可以随机访问。.(了解)3.cpu高速缓存命中率更高(相比链表)顺序表缺点:1.头部中部插入效率低——O(N)2.扩容 ——性能消耗,空间浪费
链表优点:1.任意插入删除都很方便2.扩容——不存在空间浪费(按需申请空间)链表缺点:1.扩容——每次都要申请malloc浪费了时间2.不能随机访问
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。