栈的基本操作实现算法_张小鱼༒的博客-CSDN博客
目录
系列文章目录
文章目录
前言
一、顺序结构的链式表示——单链表
1.链表的相关介绍
1.1链表的概念及结构
1.2、单链表
1.3、单链表的优缺点
1.4、补充:顺序表的优缺点
二、单链表的一些基本操作与结构定义
1、单链表的实现
2、单链表的结构定义
3、单链表结点的创建
4、单链表的基本操作接口
5、主要的几种操作介绍
5.1、头插法建立单链表
5.2尾插法建立单链表
5.3、查找结点
5.4、修改结点
5.5、插入结点
总结
本文仅简单介绍单链表这种数据结构
以下是本篇文章正文内容,下面案例可供参考
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,而链表的结构其实就像一辆火车一样。
在链表(SListl)当中,每个节点(SListNode)都存储着一个数据(data),还有一个指向下个节点的指针(next)
单链表用结点存储了数据以及下一个结点的地址,因此结点一般分为多个部分,即数据域与指针域,数据域存储有效数据,指针域存储下一个结点的地址。同时单链表有只有一个指针域,双链表有两个指针域。同时其最后一个节点是指向一个空指针。
下面我们实现的单链表是很多数据结构的子结构,也就是单向不带头非循环链表。
单链表的结构与顺序表是完全不同的,分为俩个部分数据域和指针域
typedef struct SListNode
{
int data;
struct SListNode* next;//存储下一个节点的地址
}SListNode;
我们也可以使用typedef操作符重命名,方便后面接口操作。
单链表的创建,不用像顺序表一样需要初始化的,是由一个个节点组成,需要多少个结点就创建多少个结点,我们可以单独写出一个测试函数测试单链表的创建,方便调试,下面我们利用上面这个结构创建一个单链表。
typedef int SLTDataType;//统一数据类型
SLTDataType* BuySListNode(SLTDataType x);//申请结点
void SListPrint(SListNode* phead);//打印链表
void SListPushBack(SListNode** pphead, SLTDataType x);//尾插
void SListPushFront(SListNode** pphead, SLTDataType x);//头插
void SListPopBack(SListNode** pphead);//尾删
void SListPopFront(SListNode** pphead);//头删
SLTDataType *SListFind(SListNode* pphead, SLTDataType x);//查找
//在pos位置之前插入(pos第几个元素的地址)
//和顺序表的下标越界不同,链表不存在下标,pos地址必须为find函数找到
void SListInsert(SListNode** pphead, SListNode*pos, SLTDataType x);
//在pos位置之后插入
void SListInsertAfter(SListNode* pos, SLTDataType x);
//删除pos位置
void SListErase(SListNode** pphead, SListNode* pos);
//删除pos下一位的位置
void SListEraseAfter( SListNode* pos);
void SListDestroy(SListNode** pphead);//摧毁链表
#include
#include
//单链表的结构定义
typedef struct LNode
{
int data; //data存放结点数据域
struct LNode *next; //指向后继结点的指针
}LNode; //定义单链表结点类型
//头插法建立单链表
void createlistF(LNode *&L, int a[], int n)
{
LNode *s;
int i;
L = (LNode*)malloc(sizeof(LNode));
L ->next = NULL;
for(i=0;idata = a[i];
//下面两句为头插法的关键步骤
s ->next = L ->next; //s所指新结点的指针域next指向L中的开始结点
L ->next = s; //头结点的指针域next指向s结点,使得s成为新的开始结点
}
}
//打印链表数据
void printfList(LNode *L)
{
LNode *temp = L;
int count = 0;
printf("表中的元素为:\n");
while(temp->next)
{
temp = temp->next;
printf("%d\t",temp->data);
count++;
if(count%5==0)
{
printf("\n");
}
}
printf("\n");
}
int main()
{
LNode *L;
int n;
printf("请输入数组的个数:");
scanf("%d",&n);
int a[n];
printf("请输入数组中的数(用空格分开):\n");
for(int i=0;i
#include
#include
typedef struct LNode
{
int data; //data中存放结点的数据域
struct LNode *next; //指向后继结点的指针
}LNode; //定义单链表结点类型
//尾插法建立链表
void createlistR(LNode *&L, int a[], int n) //要改变的变量用引用型
{
LNode *s,*r; //s用来指向新申请的结点,r之中指向L的终端结点
int i;
L = (LNode *)malloc(sizeof(LNode)); //申请L的头结点空间
L -> next = NULL;
r = L; // r指向头结点,因为此时头结点就是终端结点
for(i=0;idata = a[i];// 用新申请的结点来接受a中的一个元素
r ->next = s; // 用来接纳新结点
r = r ->next; // r指向终端结点,以便于接纳下一个到来的结点
}
r ->next = NULL; // 数组a中所有的元素都已经装入链表L中,L的终端结点的指针域置为NULL,L建立完成
}
//打印链表数据
void printfList(LNode *L)
{
LNode *temp = L;
int count = 0; //计数器
printf("表中的元素为:\n");
while(temp->next)
{
temp = temp->next;
printf("%d\t",temp->data);
count++;
if(count%5==0) //每5个元素作为一行
{
printf("\n");
}
}
printf("\n");
}
int main()
{
LNode *L;
int n;
printf("请输入数组的个数:");
scanf("%d",&n);
int a[n];
printf("请输入数组中的数(用空格分开):\n");
for(int i=0;i
#include
#include
//单链表的结构定义
typedef struct LNode
{
int data; //data存放结点数据域
struct LNode *next; //指向后继结点的指针
}LNode; //定义单链表结点类型
//头插法建立单链表
void createlistF(LNode *&L, int a[], int n)
{
LNode *s;
int i;
L = (LNode*)malloc(sizeof(LNode));
L ->next = NULL;
for(i=0;idata = a[i];
s ->next = L ->next;
L ->next = s;
}
}
//打印链表数据
void printfList(LNode *L)
{
LNode *temp = L;
int count = 0; //计数器
printf("表中的元素为:\n");
while(temp->next)
{
temp = temp->next;
printf("%d\t",temp->data);
count++;
if(count%5==0) //每5个元素作为一行
{
printf("\n");
}
}
printf("\n");
}
//在链表L中查找与e相等的元素,找到的话返回其位置, 否则返回未找到。
int searchElem(LNode *L, int e)
{
LNode *temp = L;
int i = 1;
int p = 0;
while(temp ->next)
{
temp = temp ->next;
if(e == temp->data)
{
p = i;
printf("找到了与%d相等元素位置为%d\n",e,p);
return 1;
}
i++;
}
printf("抱歉,没有找到!");
return -1;
}
int main()
{
LNode *L;
int n;
printf("请输入数组的个数:");
scanf("%d",&n);
int a[n];
printf("请输入数组中的数(用空格分开):\n");
for(int i=0;i
#include
#include
//单链表的结构定义
typedef struct LNode
{
int data; //data存放结点数据域
struct LNode *next; //指向后继结点的指针
}LNode; //定义单链表结点类型
//头插法建立单链表
void createlistF(LNode *&L, int a[], int n)
{
LNode *s;
int i;
L = (LNode*)malloc(sizeof(LNode));
L ->next = NULL;
for(i=0;idata = a[i];
s ->next = L ->next;
L ->next = s;
}
}
//打印链表数据
void printfList(LNode *L)
{
LNode *temp = L;
int count = 0; //计数器
printf("表中的元素为:\n");
while(temp->next)
{
temp = temp->next;
printf("%d\t",temp->data);
count++;
if(count%5==0) //每5个元素作为一行
{
printf("\n");
}
}
printf("\n");
}
// 修改单链表L的第p个位置上的结点
int replace(LNode *L, int p, int e)
{
LNode *temp = L;
temp = temp ->next;
for(int i=1;inext;
}
temp ->data = e;
}
int main()
{
LNode *L;
int n;
printf("请输入数组的个数:");
scanf("%d",&n);
int a[n];
printf("请输入数组中的数(用空格分开):\n");
for(int i=0;i
#include
#include
//单链表的结构定义
typedef struct LNode
{
int data; //data存放结点数据域
struct LNode *next; //指向后继结点的指针
}LNode; //定义单链表结点类型
//头插法建立单链表
void createlistF(LNode *&L, int a[], int n)
{
LNode *s;
int i;
L = (LNode*)malloc(sizeof(LNode));
L ->next = NULL;
for(i=0;idata = a[i];
s ->next = L ->next;
L ->next = s;
}
}
//打印链表数据
void printfList(LNode *L)
{
LNode *temp = L;
int count = 0; //计数器
printf("表中的元素为:\n");
while(temp->next)
{
temp = temp->next;
printf("%d\t",temp->data);
count++;
if(count%5==0) //每5个元素作为一行
{
printf("\n");
}
}
printf("\n");
}
//在链表L的第p个位置上插入元素e
void insertElem(LNode *L, int p, int e)
{
LNode *temp = L;
int i = 0;
while(inext;
++i;
}
LNode *s = (LNode*)malloc(sizeof(LNode)); //创建新结点
s ->data = e;
s->next = temp ->next;
temp ->next = s;
}
int main()
{
LNode *L;
int n;
printf("请输入数组的个数:");
scanf("%d",&n);
int a[n];
printf("请输入数组中的数(用空格分开):\n");
for(int i=0;i
5.6、删除结点
#include
#include
//单链表的结构定义
typedef struct LNode
{
int data; //data存放结点数据域
struct LNode *next; //指向后继结点的指针
}LNode; //定义单链表结点类型
//头插法建立单链表
void createlistF(LNode *&L, int a[], int n)
{
LNode *s;
int i;
L = (LNode*)malloc(sizeof(LNode));
L ->next = NULL;
for(i=0;idata = a[i];
s ->next = L ->next;
L ->next = s;
}
}
//打印链表数据
void printfList(LNode *L)
{
LNode *temp = L;
int count = 0; //计数器
printf("表中的元素为:\n");
while(temp->next)
{
temp = temp->next;
printf("%d\t",temp->data);
count++;
if(count%5==0) //每5个元素作为一行
{
printf("\n");
}
}
printf("\n");
}
//删除单链表L中第p位置上的结点
void deleteElem(LNode *L, int p, int *e)
{
LNode *temp = L;
int i = 0;
//找到删除结点的上一结点,即第p-1个结点
while(inext;
++i;
}
LNode *q = temp->next; //定义一个q指针指向被删除结点
*e = q->data; //保存被删除的结点的数据域
temp->next = q->next; //删除结点的上一个结点的指针域指向删除结点的下一个结点
free(q); //释放q所指结点的内存空间
}
int main()
{
LNode *L;
int n;
printf("请输入数组的个数:");
scanf("%d",&n);
int a[n];
printf("请输入数组中的数(用空格分开):\n");
for(int i=0;i
以上就是今天要讲的内容,本文仅仅简单介绍了单链表的一些基本操作与创建方法,以及相关的特点,希望对你们有所帮助,也欢迎大佬的指正。