赞
踩
- typedef int SLDataType;//节点类型,S 表示节点,L表示链表
- typedef struct SListNode
- {
- SLDataType data;
- struct SListNode* next;
- }SLNode;
- #pragma once
- #include <stdio.h>
- #include <stdlib.h>//用一个就申请一个空间
- #include <assert.h>
-
- typedef int SLDataType;
- typedef struct SListNode
- {
- int data;
- struct SListNode* next;
- }SLNode;
-
- //链表打印
- void SLPrint(SLNode* phead);
- void SLPrint(SLNode* phead)//phead 表示头节点
- {
- SLNode* pcur = phead;//pcur 临时的节点
- while (pcur != 0)
- {
- printf("%d->", pcur->data);
- pcur = pcur->next;
- }
- printf("NULL\n");
- }
- void SListTest1()
- {
- SLNode* Node1 = (SLNode*)malloc(sizeof(SLNode));//初始化
- Node1->data = 1;
- SLNode* Node2 = (SLNode*)malloc(sizeof(SLNode));
- Node2->data = 2;
- SLNode* Node3 = (SLNode*)malloc(sizeof(SLNode));
- Node3->data = 3;
- Node1->next = Node2;
- Node2->next = Node3;
- Node3=->next = NULL;//最后一个置为NULL
-
- //打印链表
- SLPrint(Node1);
- }
- //新空间
- SLNode* SLBuyNode(SLDataType x)
- {
- SLNode* Newnode = (SLNode*)malloc(sizeof(SLNode));
- if (Newnode == NULL)
- {
- perror("malloc New");
- exit(1);//非0表示异常返回,会导致直接跳出整个程序
- }
- //开辟完新空间记得放入数据
- Newnode->data = x;
- Newnode->next = NULL;
-
- return Newnode;//开辟完空间要记得返回
- }
- //链表尾插
- void SLPushBack(SLNode** pphead, SLDataType x)
- {
- assert(pphead);//这里不能判断*pphead,因为有可能本来就是空链表
- //尾插的时候需要看是否为NULL,空链表和非空链表
- SLNode* Newnode = SLBuyNode(x);//把需要插入的值传过去
- if (*pphead == NULL)
- {
- *pphead = Newnode;//如果是NULL就把新开辟的给到头节点
- }
- else
- {
- SLNode* ptail = *pphead;
- while (ptail->next != NULL)//查找尾节点
- {
- ptail = ptail->next;
- }
- ptail->next = Newnode;//新节点里面已经置为空指针
- }
- }
- SListTest2()
- {
- SLNode* node = NULL;//新创建的节点要初始化
- //测试尾插
- //SLPushBack(&node, 2);
- //SLPushBack(&node, 3);
- //SLPushBack(&node, 4);
- //SLPrint(node);
- //测试头插
- SLPushFront(&node, 4);
- SLPushFront(&node, 3);
- SLPushFront(&node, 2);
- SLPushFront(&node, 1);
- SLPrint(node);
- }
1.可以看上面你要&node的地址才能对node改变,而不是他创建node,而你就传node,这个就和传值调用不就一样了吗?
- //链表头插
- void SLPushFront(SLNode** pphead, SLDataType x)
- {
- assert(pphead);//这里不能判断*pphead,因为有可能本来就是空链表
- SLNode* newnode = SLBuyNode(x);
- newnode->next = *pphead;//把之前的头节点给到新节点
- *pphead = newnode;//头插成为新节点
- }
- //链表尾删
- void SLDelBack(SLNode** pphead)
- {
- //传过来的地址必须有效
- assert(pphead && *pphead);
- //首先要考虑2种情况,有链表的情况,一个节点的情况
- if ((*pphead)->next == NULL)
- {
- free(*pphead);
- *pphead = NULL;
- }
- else
- {
- SLNode* ptail = *pphead;//再创建一个临时的指针更好,可以避免优先级问题,还有能保留源地址
- SLNode* pcur = *pphead;
- while (ptail->next)
- {
- pcur = ptail;//ptail指向前的一个节点
- ptail = ptail->next;
- }
- free(ptail);//直接free ptail
- ptail = NULL;
- pcur->next = NULL;
- }
- }
- void SLDelFront(SLNode** pphead)
- {
- assert(pphead && *pphead);//链表为空就没有删除的意义了
- SLNode* next = (*pphead)->next;//保存下一个节点
- free(*pphead);
- *pphead = next;
- }
- SLNode* SLFind(SLNode* phead, SLDataType x)
- {
- assert(phead);//等价与 phead != NULL
- SLNode* pcur = phead;//可能需要多次查找
- while (pcur)//结束调试是最后一个节点的后一个NULL,往下查找无意义
- {
- if (pcur->data == x)
- {
- return pcur;//如果到了当前节点,就找到当前节点下面的值
- }
- pcur = pcur->next;//访问到当前节点指向的下一个,没有向下查找条件会死循环
- }
- return NULL;
- }
- void SLInsert(SLNode** pphead, SLNode* pos, SLDataType x)
- {
- assert(pphead && *pphead);
- assert(pos);//不能为空,为你还找啥呢?
- if (pos == *pphead)
- {
- SLPushFront(pphead, x);
- }
- else
- {
- SLNode* prev = *pphead;//prev 表示 pos的前一个节点
- SLNode* newnode = SLBuyNode(x);
- while (prev->next != pos)//如过指向的下一个节点不是pos,则继续往下找
- {
- prev = prev->next;
- }
- newnode->next = pos;
- prev->next = newnode;
- }
- }
- //在指定位置之后插入
- void SLInsetAfter(SLNode* pos, SLDataType x)
- {
- assert(pos);//指定为空,还怎么删除
- SLNode* newnode = SLBuyNode(x);
- newnode->next = pos->next;
- pos->next = newnode;//pos->next 原先指向的数据已经给到newnode->next
- }
- //删除pos节点
- void SLErase(SLNode** pphead, SLNode* pos)
- {
- assert(pphead && *pphead);
- assert(pos);
- //两种情况:1.pos节点没有指向第一个有效节点,反之就是指向了
- if (pos == *pphead)
- {
- //相当于头删了
- SLDelFront(pphead);
- }
- else
- {
- SLNode* prev = *pphead;
- while (prev->next != pos)//他指向的节点,等于了pos就相当于找到了前一个节点
- {
- prev = prev->next;//通过当前的找到下一个,直到找到pos
- }
- //prev -> pos -> pos->next
- prev->next = pos->next;
- free(pos);
- pos = NULL;
- }
- }
- //删除pos节点之后的
- void SLEraseAfter(SLNode* pos)
- {
- assert(pos && pos->next);//都不能为空
- SLNode* del = pos->next;
- pos->next = del->next;
- free(del);
- del = NULL;
- }
- //销毁链表
- void SLDesTroy(SLNode** pphead)
- {
- SLNode* pcur = *pphead;
- while (pcur)
- {
- SLNode* del = pcur->next;//在销毁之前保存下一个节点的地址
- free(pcur);
- pcur = del;
- }
- pcur = NULL;
- }
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <assert.h>
- #include <stdlib.h>
- typedef int SLDataType;
- typedef struct SListNode
- {
- SLDataType val;
- struct SListNode* next;
- }SLNode;
-
- //链表打印
- void SLPrint(SLNode* phead);
-
- //链表尾插和头插
- void SLPushBack(SLNode** pphead, SLDataType x);
- void SLPushFront(SLNode** pphead, SLDataType x);
-
- //链表头删和尾删
- void SLDelBack(SLNode** pphead);
- void SLDelFront(SLNode** pphead);
-
- //链表查找
- SLNode* SLFind(SLNode* phead, SLDataType x);
-
- //链表pos之前插入
- void SLInset(SLNode** pphead, SLNode* pos, SLDataType x);
-
- //链表pos之后插入
- void SLInsetAfter(SLNode* pos, SLDataType x);
-
- //链表pos节点删除
- void SLErase(SLNode** pphead,SLNode* pos);
-
- //链表pos之后删除
- void SLEraseAfter(SLNode* pos);
-
- //链表的销毁
- void SLDesTroy(SLNode* pphead);
- #include "SList.h"
- void SLPrint(SLNode* phead)
- {
- SLNode* pcur = phead;
- while (pcur)//如果是pcur->next为结束条件会导致,提前结束不进入循环
- {
- printf("%d->", pcur->val);
- pcur = pcur->next;
- }
- printf("NULL\n");
- }
- //新节点空间
- SLNode* SLBuyNode(SLDataType x)
- {
- SLNode* Newnode = (SLNode*)malloc(sizeof(SLNode));
- if (Newnode == NULL)
- {
- perror("malloc new");
- exit(1);//异常返回退出整个工程
- }
- Newnode->val = x;
- Newnode->next = NULL;
- return Newnode;
- }
- //尾插
- void SLPushBack(SLNode** pphead, SLDataType x)
- {
- assert(pphead);
- SLNode* newnode = SLBuyNode(x);
- //空链表和非空链表
- if (*pphead == NULL)
- {
- *pphead = newnode;
- }
- else
- {
- SLNode* ptail = *pphead;
- while (ptail->next != NULL)
- {
- ptail = ptail->next;
- }
- ptail->next = newnode;
- }
- }
- //头插
- void SLPushFront(SLNode** pphead, SLDataType x)
- {
- assert(pphead);
- SLNode* newnode = SLBuyNode(x);
- newnode->next = *pphead;
- *pphead = newnode;//直接把第一个节点的位置给newnode,成为新的头结点
- }
-
- //尾删
- void SLDelBack(SLNode** pphead)
- {
- assert(pphead && *pphead);
- //一个节点的情况
- if ((*pphead)->next == NULL)
- {
- free(*pphead);
- *pphead = NULL;
- }
- else
- {
- SLNode* prev = *pphead;//保留的前一个节点
- SLNode* ptail = *pphead;
- while (ptail->next != NULL)//跳出循环就表示找到前一个节点了
- {
- prev = ptail;//保留了结束前的前一个地址
- ptail = ptail->next;
- }
- free(ptail);
- ptail = NULL;
- prev->next = NULL;//指向的下一个节点为NU
- }
- }
-
- //头删
- void SLDelFront(SLNode** pphead)
- {
- assert(pphead && *pphead);
- SLNode* pcur = (*pphead)->next;
- free(*pphead);
- *pphead = pcur;
- }
-
- //查找
- SLNode* SLFind(SLNode* phead, SLDataType x)
- {
- assert(phead);
- SLNode* pcur = phead;
- while (pcur)
- {
- if (pcur->val == x)
- return pcur;
- pcur = pcur->next;
- }
- return NULL;
- }
-
- //pos位置之前插入
- void SLInset(SLNode** pphead, SLNode* pos, SLDataType x)
- {
- assert(pphead && *pphead);
- assert(pos);
- SLNode* newnode = SLBuyNode(x);
- if (*pphead == pos)//因为下面一种会找不到
- {
- SLPushFront(pphead, x);//这里要传二级指针因为,要对链表进行改变
- }
- else
- {
- SLNode* prev = *pphead;
- while (prev->next != pos)
- {
- prev = prev->next;
- }
- //perv pos
- newnode->next = pos;
- prev->next = newnode;
- }
-
- }
- //pos之后插入
- void SLInsetAfter(SLNode* pos, SLDataType x)
- {
- assert(pos);
- SLNode* newnode = SLBuyNode(x);
- newnode->next = pos->next;
- pos->next = newnode;
- }
-
- //pos位置处删除
- void SLErase(SLNode** pphead, SLNode* pos)
- {
- assert(pos);
- if (*pphead == pos)//调用头删
- {
- SLDelFront(pphead);
- }
- else
- {
- SLNode* prev = *pphead;
- while (prev->next != pos)
- {
- prev = prev->next;
- }
- prev->next = pos->next;
- free(pos);
- pos = NULL;
- }
- }
-
- //pos之后删除
- void SLEraseAfter(SLNode* pos)
- {
- assert(pos && pos->next);//pos后面的一个节点也不能为NULL
- SLNode* del = pos->next;
- pos->next = del->next;
- free(del);
- del = NULL;
- }
-
- //销毁链表
- void SLDesTroy(SLNode** pphead)
- {
- SLNode* pcur = *pphead;
- while (pcur)
- {
- SLNode* del = pcur->next;//在销毁之前保存下一个节点的地址
- free(pcur);
- pcur = del;
- }
- pcur = NULL;
- }
- #include "SList.h"
- SListTest1()
- {
- SLNode* node = NULL;//新创建的节点要初始化
- //测试尾插
- //SLPushBack(&node, 2);
- //SLPushBack(&node, 3);
- //SLPushBack(&node, 4);
- //SLPrint(node);
- //测试头插
- SLPushFront(&node, 4);
- SLPushFront(&node, 3);
- SLPushFront(&node, 2);
- SLPushFront(&node, 1);
- SLPrint(node);
-
- 测试尾删
- //SLDelBack(&node);
- //SLDelBack(&node);
- //SLDelBack(&node);
- //SLDelBack(&node);
- //SLPrint(node);
-
- 测试头删
- //SLDelFront(&node);
- //SLDelFront(&node);
- //SLDelFront(&node);
- //SLDelFront(&node);
- //SLDelFront(&node);
- //SLPrint(node);
-
- //测试查找
- SLNode* find = SLFind(node,3);
- if (find)//非0值,NULL其实原本意思也是0
- printf("找到了\n");
- else
- printf("没找到\n");
-
- //pos前插入
- //SLInset(&node, find, 11);
- //SLPrint(node);
- //pos后插入
- //SLInsetAfter(find, 22);
- //SLPrint(node);
-
- //删除pos位置
- //SLErase(&node, find);
- //SLPrint(node);
-
- //删除pos位置之后的
- SLEraseAfter(find);
- SLPrint(node);
-
- SLDesTroy(&node);
- }
- int main()
- {
- SListTest1();
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。