赞
踩
目录
创建准备;
数据+指向下一个节点的指针
- // 首先定义数据的类型,方便后续更改
- typedef int SLTNodeDataType;
-
- // 创建节点
- typedef struct SListNode
- {
- SLTNodeDataType data; // 存储数据
- struct SListNode* next;// 指向下一个节点的指针
- }SLTNode;
头文件声明:
void SLTPrint(SLTNode* phead);
执行文件代码实现:
- // 链表的打印
- void SLTPrint(SLTNode* phead)
- {
- SLTNode* pcur = phead;// 保证phead指向的位置是收节点,方便后续再次遍历
- while (pcur)// 等价于 pcur != NULL;
- {
- printf("%d->", pcur->data);
- pcur = pcur->next;
- }
- printf("NULL\n");
- }
头文件声明:
void SLTPushBack(SLTNode** pphead, SLTNodeDataType x);
- // 创建新的节点
- SLTNode* SLTBuyNode(SLTNodeDataType x)
- {
- SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
- if (NULL == newnode)
- {
- perror("SLTBuyNode malloc err!");
- exit(1);
- }
-
- // 创建节点成功
- newnode->data = x;
- newnode->next = NULL;
-
- // 返回
- return newnode;
- }

执行文件代码实现:
- // 链表的尾插
- void SLTPushBack(SLTNode** pphead, SLTNodeDataType x)
- {
- // 传参不可为空
- assert(pphead);
-
- // 创建一个新的节点
- SLTNode* newnode = SLTBuyNode(x);
-
- // 空链表和非空链表
- if (*pphead == NULL)
- {
- *pphead = newnode;
- }
- else
- {
-
- // 找尾巴
- SLTNode* ptail = *pphead;
- while (ptail->next) // 等价于ptail->next !=NULL;
- {
- ptail = ptail->next;
- }
-
- // 找到尾巴,开始连接
- ptail->next = newnode;
- }
-
- }

头文件声明:
- // 链表的头插
- void SLTPushFront(SLTNode** pphead, SLTNodeDataType x);
执行文件代码实现:
- // 链表的头插
- void SLTPushFront(SLTNode** pphead, SLTNodeDataType x)
- {
- // 传参不可为空
- assert(pphead);
-
- // 创建一个新的节点
- SLTNode* newnode = SLTBuyNode(x);
-
- // 头插
- newnode->next = *pphead;
- *pphead = newnode;
- }
头插就很简单了, 只需要创建新的节点放到链表的头部,不论是空链表和非空链表,情况都是一样的,连接好后,将头指针改指向,指向新头插的节点。
头文件声明:
void SLTPopBack(SLTNode** pphead);
执行文件代码实现:
- // 链表的尾删
- void SLTPopBack(SLTNode** pphead)
- {
- // 链表不可以为空,传参不可为空
- assert(pphead && *pphead);
-
- // 链表有一个节点和多个节点
- // 一个节点
- if ((*pphead)->next == NULL)
- {
- free(*pphead);
- *pphead = NULL;
- }
- else //多个节点
- {
- // 找尾
- SLTNode* prev = *pphead;
- SLTNode* ptail = *pphead;
-
- while (ptail->next)
- {
- prev = ptail;
- ptail = ptail->next;
- }
-
- free(ptail); // 释放空间
- ptail = NULL;// 防止野指针
- prev->next = NULL;
- }
-
- }

尾删除需要影响原链表,所以传二级指针,同时尾删时我们需要注意是否节点是一个,如果是一个,删除后链表为空,申请的空间需要释放,防止造成空间浪费。如果是多个节点,我们需要找尾巴ptail,并且记录前一个节点prev,删除尾节点并且释放,置为空,将prev->next=NULL。
头文件声明:
void SLTPopFront(SLTNode** pphead);
执行文件代码实现:
- // 链表的头删
- void SLTPopFront(SLTNode** pphead)
- {
- assert(pphead && *pphead);
- SLTNode* next = (*pphead)->next;
- free(*pphead);
- *pphead = next;
- }
删除前断言所传的指针是否为空,链表是否为空,头删除前记录下一个节点,删除头节点后,将头置后。
头文件声明:
SLTNode* SLTFind(SLTNode* phead, SLTNodeDataType x);
执行文件代码实现:
- // 链表的查找
- SLTNode* SLTFind(SLTNode* phead, SLTNodeDataType x)
- {
-
- SLTNode* prev = phead;
- while (prev)// 等价于 prev != NULL;
- {
- if (prev->data == x)
- {
- return prev;
- }
- prev = prev->next;
- }
-
- // 遍历完毕没有找到,返回空。
- return NULL;
- }

头文件声明:
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTNodeDataType x);
执行文件代码实现:
- // 链表在指定位置之前插⼊数据
- void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTNodeDataType x)
- {
- // 不可以传入NULL
- assert(pphead && *pphead);
- assert(pos);
-
- // 创建一个新的节点
- SLTNode* newnode = SLTBuyNode(x);
-
- // 如果节点只有一个,就是头插
- if (pos == *pphead)
- {
- SLTPushFront(pphead, x);
- }
- else
- {
- SLTNode* pcur = *pphead;
-
- // pcur所指向的节点不为pos前一个节点
- while (pcur->next != pos)
- {
- pcur = pcur->next;
- }
-
- // pcur所指向的节点为pos前一个节点
- newnode->next = pos;
- pcur->next = newnode;
- }
- }

头文件声明:
void SLTInsertAfter(SLTNode* pos, SLTNodeDataType x);
执行文件代码实现:
- // 链表在指定位置之后插⼊数据
- void SLTInsertAfter(SLTNode* pos, SLTNodeDataType x)
- {
- assert(pos);
-
- // 创建要插入的节点
- SLTNode* newnode = SLTBuyNode(x);
-
- // 开始插入
- newnode->next = pos->next;
- pos->next = newnode;
- }
头文件声明:
void SLTErase(SLTNode** pphead, SLTNode* pos);
执行文件代码实现:
- //删除pos节点
- void SLTErase(SLTNode** pphead, SLTNode* pos)
- {
- assert(pphead && *pphead);
- assert(pos);
- if (*pphead == pos)
- {
- SLTPopFront(pphead);
- }
- else
- {
- SLTNode* prev = *pphead;
-
- while (prev->next != pos)
- {
- prev = prev->next;
- }
-
- // prev所指向的就是pos前一个节点
- prev->next = pos->next;
- free(pos);
- pos = NULL;
- }
-
- }

头文件声明:
void SLTEraseAfter(SLTNode* pos);
执行文件代码实现:
- //删除pos之后的节点
- void SLTEraseAfter(SLTNode* pos)
- {
- assert(pos && pos->next); // 传过来的参数不可以为空,pos下一个的参数也不可以是NULL
-
- SLTNode* del = pos->next;
- pos->next = del->next;
- free(del);
- del = NULL;
- }
文件声明:
void SListDesTroy(SLTNode** pphead);
执行文件代码实现:
- //销毁链表
- void SListDesTroy(SLTNode** pphead)
- {
- assert(pphead && *pphead);
- SLTNode* pcur = *pphead;
- while (pcur)
- {
- SLTNode* next = pcur->next;
- free(pcur);
- pcur = next;
- }
- // 全部销毁完后,置为空NULL;
- *pphead = NULL;
- }
- //void SListNodeText01()
- //{
- // // 创建节点
- // SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
- // node1->data = 1;
- //
- // SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
- // node2->data = 2;
- //
- // SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
- // node3->data = 3;
- //
- // SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
- // node4->data = 4;
- //
- // // 将四个节点连接起来
- // node1->next = node2;
- // node2->next = node3;
- // node3->next = node4;
- // node4->next = NULL;
- //
- // // 打印
- // SLTPrint(node1);
- //}
-
- void SLTNodeText02()
- {
- //SLTNode* plist = NULL;
-
- // 测试尾插
- //SLTPushBack(&plist, 1);
- //SLTPushBack(&plist, 2);
- //SLTPushBack(&plist, 3);
- //SLTPushBack(&plist, 4);
- /*SLTPrint(plist);*/// 1->2->3->4->NULL;
-
-
- // 测试头插
- /*SLTPushFront(&plist, 5);
- SLTPrint(plist);
- SLTPushFront(&plist, 6);
- SLTPrint(plist);
- SLTPushFront(&plist, 7);
- SLTPrint(plist);
- SLTPushFront(&plist, 8);
- SLTPrint(plist);*/
-
-
- // 测试尾删
- //SLTPopBack(&plist);
- //SLTPrint(plist);
- //SLTPopBack(&plist);
- //SLTPrint(plist);
- //SLTPopBack(&plist);
- //SLTPrint(plist);
- //SLTPopBack(&plist);
- //SLTPrint(plist);
-
-
- // 测试头删
- //SLTPopFront(&plist);
- //SLTPrint(plist);
- //SLTPopFront(&plist);
- //SLTPrint(plist);
- //SLTPopFront(&plist);
- //SLTPrint(plist);
- //SLTPopFront(&plist);
- //SLTPrint(plist);
- // 报错
- //SLTPopFront(&plist);
- //SLTPrint(plist);
-
-
- // 测试查找
- //SLTNode* find = SLTFind(plist, NULL);
- //if (find == NULL)
- //{
- // printf("没有找到!\n");
- //}
- //else
- //{
- // printf("找到了!\n");
- //}
-
-
- // 测试在pos位置之前插⼊数据
- //SLTNode* find = SLTFind(plist, 1);
- //SLTInsert(&plist, find, 11);
- //SLTPrint(plist);
-
-
- // 测试链表在指定位置之后插⼊数据
- /*SLTNode* find = SLTFind(plist, 4);
- SLTInsertAfter(find, 11);
- SLTPrint(plist);*/
-
- // 测试删除pos之后的节点
- /*SLTNode* find = SLTFind(plist, 1);
- SLTEraseAfter(find);
- SLTPrint(plist);*/
-
- // 测试销毁
- SListDesTroy(&plist);
- }
-
- int main()
- {
- //SListNodeText01();
- SLTNodeText02();
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。