前言
提示:文本为数据解构(三)单链表:
本文具体讲解单链表的具体使用方法
提示:以下是本篇文
系列文章目录
第一章 数据解构(一)
第二章 顺序表的具体使用方法.数据解构(二)
文章目录
前言
系列文章目录
文章目录
一、单链表视图
二、单链表使用方式
1.定义一个结构体
2.初始化
3.扩容
4.尾插
5.尾减
方法一(笨方法):
方法二:
三.总结
6.头加
7.头减
8.打印
提示:以下是本篇文章正文内容,下面案例可供参考
回顾上文说到
顺序表的使用方法
由于顺序表的缺点:
- 空间不够,需要扩容,扩容后有的扩容空间用不到,浪费空间.
- 插入数据或移动数据,删除数据都会有消耗.
所有有了单链表
单链表的优势:
- 按需来扩容,不多不少刚刚好,不用就释放,合理使用空间.
- 从头插入数据不需要挪动数据,美滋滋(不浪费空间).
单链表的缺点:
- 每一个数据都需要用指针去访问每一个节点.
- 不支持“点名访问”就像数组访问一样访问下标.
一、单链表视图
图片如下(示例):
二、单链表使用方式
1.定义一个结构体
代码如下(示例):
#include <stdio.h>
#include <stdlib.h>
typedef int SLDataType;//SLDataType
typedef struct Link_List
{SLDataType data;//存储值struct List* next;//存储下一个地址
}List;
SLDataType data;//存储值
struct List* next;//存储下一个地址
2.初始化
代码如下(示例):
List* str=NULL;
为一个空,主要目的为在极端可能的情况,如:头插,尾插时没有节点.
3.扩容
增容的目的是为了在输入数据时有可用空间,不多不少刚刚好
代码如下(示例):
//增容
List* SListAdd(SLDataType x)
{List* newlist = (List*)malloc(sizeof(List));if (newlist == NULL){//增容失败直接返回return;}newlist->data = x;newlist->next = NULL;return newlist;
}
4.尾插
代码如下(示例):
//尾插
void SListPushBack(List** pplist, SLDataType x)
{//增加可以模块化/*List* newlist = (List*)malloc(sizeof(List));newlist->data = x;newlist->next = NULL;*/List* newlist = SListAdd(x);//创建一个新的节点if (*pplist==NULL)//判断是否有节点{//没有就把newlist给pplist*pplist = newlist;}else{//有,就找尾(null)List* tali = *pplist;//把pplist的地址给taliwhile (tali->next!=NULL){tali = tali->next;}//把newlist的地址给尾巴tali->next = newlist;}
}
5.尾减
代码如下(示例):
方法一(笨方法):
//尾删
void SLPopback(List** pplist)
{if (*pplist == NULL){return;}//判断是否只有一个节点if ((*pplist)->next==NULL){//如果是直接释放free(*pplist);*pplist = NULL;}else{List* Front = *pplist;//保存倒数第2个的List* hate = *pplist;//不断增加的while (hate->next !=NULL){hate = hate->next;if (hate->next == NULL){Front->next = NULL;break;}if (hate->next != NULL){Front = hate;}}free(hate);hate = NULL;}
}
方法二:
//尾删
void SLPopback(List** pplist)
{if (*pplist == NULL){return;}if ((*pplist)->next==NULL){free(*pplist);*pplist = NULL;}else{List* Prev = *pplist;//保存倒数第2个的List* tail = *pplist;//不断增加的while (tail->next !=NULL){Prev = tail;tail = tail->next;}free(tail);tail = NULL;Prev->next = NULL;}
}
三.总结
其实方放逻辑是一样的:
如图:
6.头加
思路:(修改一下是2的值的地址给1)
代码如下(示例):
//头插
void SLPoshFront(List** pplist, SLDataType x)
{List* newList = SListAdd(x);newList->next = *pplist;*pplist = newList;
}
7.头减
代码如下(示例):
//头删
void SLPopFront(List** pplist)
{if (*pplist==NULL){return;}else{List* newlist=*pplist;free(*pplist);*pplist = newlist->next;}
}
8.打印
代码如下(示例):
//打印
void SLPrintf(List* plist)
{List* LSfirst = plist;while (LSfirst!=NULL)//判断是否有下一个节点{printf("%d", LSfirst->data);//打印当前节点的值LSfirst = LSfirst->next;//寻找下一个节点}printf("\n");
}
while (LSfirst!=NULL)//判断是否有下一个节点
{
printf("%d", LSfirst->data);//打印当前节点的值
LSfirst = LSfirst->next;//寻找下一个节点
}