数据结构——单链表 创建 清空 插入 删除 查询 输出 完整源码
完整代码在最后一.单链表基本操作1.初始化1)创建结构体,储存节点的数据+指针域; 2)创建指向结构体的指针; 3)用结构体定义单链表; 4)初始化链表头节点:为头节点开辟内存; 5)判断内存是否开辟成功; 6)头节点的指针域置空,使链表长度为0。typedef struct Node//1{ElemType data;struct Node *next;}Node;typedef struct
完整代码在最后
一.单链表基本操作
1.初始化
1)创建结构体,储存节点的数据+指针域; 2)创建指向结构体的指针; 3)用结构体定义单链表; 4)初始化链表头节点:为头节点开辟内存; 5)判断内存是否开辟成功; 6)头节点的指针域置空,使链表长度为0。
typedef struct Node//1
{
ElemType data;
struct Node *next;
}Node;
typedef struct Node *LinkList;//2
Status InitList(LinkList& L)//3
{
L=(Node*)malloc(sizeof(Node));//4
if(L==NULL)//5
{
printf("申请内存空间失败\n");
}
L->next=NULL;//6
}
2.创建单链表(尾插法)
1)生成新结点p和尾结点r; 2)为新节点开辟内存; 3)存入数据域; 4)存入指针域:把原来的尾结点指针域存入,即在末尾插入p; 5)更新r,使其依然为链表尾结点; 6)尾结点指针域置空
void CreateListTail(LinkList *L,int n)
{
LinkList p,r;//1
while(n--)
{
p=(Node*)malloc(sizeof(Node));//2
scanf("%d",&p->data);//3
r->next=p;//4
r=p;//5
}
r->next=NULL;
}
3.整表清除
1)结点p储存头结点; 2)判断p是否到表尾,没到就进入以下循环; a.结点q指向p下一个结点; b.释放p结点; c.p指向q结点。 3)头指针置空,相当于初始化链表。
-
注:不能用p=p->next代替q,∵在free(p)时也释放了指针域,∴p->next不存在。
Statue ClearList(ListLine *L)
{
ListLine p,q;
p=(*L)->next;//1
while(p)//2
{
q=p->next;//a
free(p);//b
p=q;//c
}
(*L)->next=NULL;
}
4.获取第 i 个元素
1)用p指向链表第一个元素; 2)用j遍历链表,直到找到i或p已经到链表结尾,即p=NULL; 3)如果没找到,p指向下一个结点; 4)若退出循环时p为NULL或i元素不存在,则返回ERROR; 5)若找到就把数据存入。
Statue GetElem(LinkList *L,int i,int *e)
{
int j=1;
p=(*L)->next;//1
while(j<i&&p)//2
{
p=p->next;//3
j++;
}
if(j>i||!p)//4
{
return ERROR;
}
*e=p->data;//5
return OK;
}
5.插入元素
在第i位后插入元素e。变成a,e,a+1。
1)遍历链表找到第i位; 2)创立要插入的新节点s; 3)开辟新节点s的内存; 4)s的数据域存入e; 5)连接e与a+1:把a+1的指针域给新结点s; 6)连接a与e:把s给a的指针域。
Statue ListInsert(LinkList *L,int i,ElemType e)
{
//1
int j=1;
LinkList p;
p=(*L)->next;//p从头开始找:将链表头结点给p
while(p&&j<i)
{
p=p->next;
j++;
}
if(!p||j>i)
{
return ERROR;
}
LinkList s;//2
s=(Node*)malloc(sizeof(Node));//3
s->data=e;//4
s->next=p->next;//5
p->next=s;//6
return OK;
}
6.删除元素
删除i位的元素,并把删除的元素值返回到e中。
1)遍历列表找到i位,注:∵要删除p->next结点,∴p->next不能为NULL; 2)将预删除的结点储存在q内; 3)将p->next赋值为q->next,即进行了p->next=p->next->next操作; 4)把q里的数据——需删除的数据,给e; 5)释放结点q。
Statue ListDelete(LinkList *L,int i,ElemType *e)
{
//1
int j=1;
LinkList p;
p=(*L)->next;
while(p->next&&j<i)
{
p=p->next;
j++;
}
if(!(p->next)||j>i)
{
return ERROR;
}
LinkList q;
q=p->next;//2
p->next=q->next;//3
*e=q->data;//4
free(q);//5
return OK;
}
7.输出链表
void OutPutList(LinkList *L)
{
LinkList p;
p=(*L)->next;
while(p)
{
printf("%d\n",p->data);
}
}
完整代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>//用于生成随机数
typedef int Status;//用Status来进行替代int,方便数据类型的修改
typedef int ElemType;
#define OK 1;
#define ERROR 0;
//单链表储存结构
typedef struct Node//定义结构体LNode
{
ElemType data;//结点数据域
struct Node* next;//结点指针域
}Node;
typedef struct Node* LinkList;//LinkList为指向结构体Node的指针类型
//初始化一个空的单链表L
Status InitList(LinkList& L) //InitList()顺序表的初始化函数
{
L = (Node*)malloc(sizeof(Node)); //申请空间,生成新结点作为L头结点
if (L == NULL) //判断是否有足够的内存空间
{
printf("申请内存空间失败\n");
}
L->next = NULL; //头结点的指针域置空,初始长度为0
return OK;
}
//尾插法创建链表
void CreateListTail(LinkList* L, int n)//*L即调用已经存在的线性表L
{
LinkList p, r;//L:指整个单链表;p:需创建的新节点;r:指向尾结点的变量。
r = *L;//r指向尾部节点
printf("1.输入初始数据\n2.自动生成数据\n");//链表生成类型选择
int a;
scanf("%d", &a);
if (a == 1)
{
while (n--)
{
p = (Node*)malloc(sizeof(Node));//为新结点开辟内存
scanf("%d", &p->data);//读取数据
r->next = p;//在原来的尾结点r后存入
r = p;//更新尾结点
}
r->next = NULL;//链表结束
}
else if(a==2)
{
srand(time(0));//初始化随机数种子
r = *L;//r指向链表尾部
while (n--)
{
p = (Node*)malloc(sizeof(Node));//生成新结点
p->data = rand() % 100 + 1;//随机产生100以内的数
r->next = p;//将新结点添加到表尾
r = p;//更新尾结点:将新结点更新为尾结点
}
r->next = NULL;//表示链表结束
}
printf("链表创建成功!\n");
}
//整表删除,即变成空表
Status ClearList(LinkList* L)
{
LinkList p, q;
p =(*L)->next;//使p指向线性表第一个结点
while (p)//如果p不为NULL
{
q = p->next;//q指向p的下一个结点,防止释放p后找不到下一个结点
free(p);//释放p结点
p = q;//p指向下一个结点
}
(*L)->next = NULL;//使头结点为空,相当于链表初始化时的操作
return OK;
}
//查找,读取元素,获取第i个元素数据,返回到e
Status GetElem(LinkList *L, int i, ElemType* e)
{
int j=1;//计数,最后一个结点是NULL,不需要遍历∴从1开始计
LinkList p;
p=(*L)->next;//p从头结点开始找
//遍历链表,找到第i个元素
while (j <i&&p)//若没找到||p=NULL退出
{
p=p->next;//指向下一个结点
j++;
}
if (!p||j>i)//p为空||不存在i结点时
{
printf("出错!查找位置在链表之外!\n");
return ERROR;
}
*e = p->data;
return OK;
}
//在位置i插入元素e,使链表成为 a,e,a+1
Status ListInsert(LinkList* L, int i, ElemType *e)
{
//先遍历找到第i个结点
int j=1;
LinkList p;
p = (*L)->next;//p指向链表头结点
if (i == 0)//头结点插入特判
{
LinkList s;
s = (Node*)malloc(sizeof(Node));
s->data = *e;//存数据域
s->next = (*L)->next;//把原头结点给s的下一个结点
(*L)->next = s;//更新新结点
printf("成功!\n");
return OK;
}
while (j < i && p)
{
p=p->next;
j++;
}
if (!p || j > i)//没找到
{
printf("出错!插入位置在链表之外!\n");
return ERROR;
}
//找到位置后插入
LinkList s;//创建要插入的新结点
s= (Node*)malloc(sizeof(Node));//为新节点开辟内存
s->data = *e;//储存数据域
s->next = p->next;//将p后继结点给s的后继,即连接e和a+1
p->next = s;//将s给p的后继,即连接a和e
printf("成功!\n");
return OK;
}
//删除第i个元素,并用e返回其值
Status ListDelete(LinkList* L, int i, ElemType* e)
{
//遍历找到第i个结点
int j=1;
LinkList p;
p = (*L)->next;
if (i == 1)//若是头结点需特判
{
*e = p->data;
(*L)->next = p->next;//使链表头结点直接指向下一个
printf("删除元素的值为:%d\n", *e);
printf("成功!\n");
return OK;
}
i--;
while (j < i && p->next)//∵需删除p后的结点,∴p->next必须存在
{
p = p->next;
j++;
}
if (!(p->next) || i < j)
{
printf("出错!删除位置在链表之外!\n");
return ERROR;
}
LinkList q;
q = p->next;//将预删除的结点给q
p->next = q->next;//p连接需删除结点后的结点,即p->next=p->next->next
*e = q->data;//删除结点中的数据给e
free(q);//释放删除的结点
printf("删除元素的值为:%d\n", *e);
printf("成功!\n");
return OK;
}
//输出链表
void OutPutList(LinkList* L)
{
LinkList p;
p = (*L)->next;
while (p)
{
printf("%d\n", p->data);
p = p->next;
}
}
int main()
{
Node *L;
int n,i,e,q;
InitList(L);
//目录
printf(" 目录\n");
printf("1.创建链表\n2.查找列表元素\n3.清空链表\n4.插入元素\n5.删除元素\n6.输出链表\n\n");
while (~scanf("%d", &q))
{
if (q == 1)
{
printf("请输入链表数据个数:\n");
scanf("%d", &n);
CreateListTail(&L, n);
}
else if (q == 2)
{
scanf("%d", &i);
GetElem(&L, i, &e);
}
else if (q == 3)
{
ClearList(&L);
printf("链表已清空!\n");
}
else if(q==4)
{
printf("请输入需插入的位置:\n");
scanf("%d", &i);
printf("请输入需插入元素的值:\n");
scanf("%d", &e);
ListInsert(&L, i, &e);
}
else if (q == 5)
{
printf("请输入需删除的元素位置:\n");
scanf("%d", &i);
ListDelete(&L, i, &e);
}
else if (q == 6)
{
printf("\n");
OutPutList(&L);
}
printf(" 目录\n");
printf("1.创建链表\n2.查找列表元素\n3.清空链表\n4.插入元素\n5.删除元素\n6.输出链表\n\n");
}
return 0;
}
运行截图:

更多推荐

所有评论(0)