数据结构线性表的链式存储结构(单链表)的表示及其基本操作

这篇博客详细介绍了单链表的各种操作,包括初始化链表、重置(清空)链表、销毁链表、计算链表长度、获取指定位置元素、定位元素及其前后继、插入元素、删除元素、输出链表、使用头插法输入元素以及逆置链表。每种操作都配有相应的函数实现,并提供了实际调用示例。
摘要由CSDN通过智能技术生成

头文件 宏定义 部分变量

#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW -2 
#define ERROR 0
#define OK 1

typedef int Status;
typedef int Elemtype;
typedef struct LNode{
   
	Elemtype data;
	struct LNode * next;
}LNode,* LinkList;
Elemtype flag=0;//flag用于判断链表是否初始化 0:未初始化 1:已初始化
Elemtype cflag=0;//cflag用于判断链表是否为空 0:空  1:不空 

初始化一个空的链表

注:L是指向头结点的指针(也叫头指针,不知道什么是头结点,首元结点,好吧,简要说下)
首元结点:是指链表中用来存储数据元素的节点中的第一个节点
头结点:指在链表的首元节点之前附设的一个结点,数据域内只放空表标 志和表长等信息,也可以什么都不放
什么?为什么要这样设置?
这。。。。。。。
当然是因为这是前辈们的智慧喽
单链表头结点、首元节点详解
嗯,为什么形参定义是LinkList * L呢?
因为我们要改变头指针的指向,分配一个大小是LNode的内存空间,让头指针指向它,如果不需要改变头指针的指向,我们就只需要定义成LinkList L即可,然后让头结点的指针域为空,代表这是个空表,返回OK代表初始化成功。

Status InitList(LinkList * L)
{
   
	*L=(LinkList)malloc(sizeof(LNode));
	if(!*L))
	{
   
		exit(OVERFLOW);
	}
	(*L)->next=NULL;
	return OK;
} 

调用

case 1:
				printf("初始化或重置链表\n");
				printf("初始化请按1\n");
				printf("重置链表请按2\n");
				scanf("%d",&elem);
				if(elem==1)
				{
   				 
				  flag=InitList(&L);
				  if(flag==0)
				    printf("初始化失败\n");
				  else
				    printf("初始化成功\n"); 	 
				} 
				if(elem==2)
				{
   
					if(flag==1)
					{
   
						cflag=ClearList(L);
					    printf("链表已清空\n");
					}else
					{
   
						printf("链表未初始化\n");
					}  					  
				}
				system("pause");
				break;

重置链表(清空链表)

使p指向首元结点,如果p不为空,进入循环,让q指向p的后继结点,然后释放p所指向的 结点,p再移到下一个结点,q就像一个引路人,引着 p遍历完链表,释放所有的元素结点。当p指向尾结点进入循环后,q就为空,释放p后,p=q ,p为空,不再执行循环,所有元素结点均被清空。令L的指针域为空,返回ERROR代表空表标志

Status ClearList(LinkList L)
{
   
	LinkList p,q;
	p=L->next;
	while(p)
	{
   
		q=p->next;
		free(p);
		p=q;
	}
	L->next=NULL;
	return ERROR;
}

调用

case 3:
			    if(flag!=0)
				{
   
					cflag=ClearList(L);
					printf("链表已清空\n");					
				}else
				{
   
					printf("链表未初始化\n");
				}
				system("pause");
				break;

销毁链表

遍历,然后释放每个结点所分配的空间。

Status DestroyList(LinkList * L) 
{
   
	LinkList p,q;
	p=(*L)->next;
	while(p)
	{
   
		q=p->next;
		free(p);
		p=q;
	}
	p=*L;
	free(p);
	return ERROR;	
}

调用

case 2:
				if(flag!=0)
				{
   
					printf("销毁链表\n");
					flag=DestroyList(&L);
					printf("销毁成功\n");
				}else
				{
   
					printf("链表未初始化\n");
				}
				system("pause");
				break;

求链表的长度

定义一个计数器count,遍历到每个结点时,count++;直到遍历到最后一个结点,尾结点的指针域(为空)赋值给p,count+1;无法再次进行循环,返回count;

Status ListLength(LinkList L)
{
   
	Elemtype count=0;
	LinkList p;
	p=L->next;
	while(p)
	{
   
		p=p->next;
		count++;
	}
	return count; 
}

调用

case 4:
			    if(flag!=0)
				{
   
					printf("链表的长度为%d\n",ListLength(L));
				}else
				{
   
					printf("链表未初始化\n");
				}
				system("pause");
				break;

求指定位置的元素值

定义一个指针p指向头结点,当i=1时,p=p->next,指向第一个结点,当i=position时,指向所找的位置,返回该位置的数据域即可。

Status GetElem(LinkList L,Elemtype position)
{
   
	Elemtype i;
	LinkList p;
	p=L;
	for(i=1;i<=position;i++)
	{
   
		p=p->next;
	}
	return p->data;
} 

调用

case 5:
			    if(flag!=0)
				{
   
					printf("请输入你所查找的位置\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L))
	                {
   
	                   	printf("不存在这个位置\n");
					}else
					{
   
						elem=GetElem(L,position);
					    printf("该位置上的元素是%d\n",elem);
					}					
			    }else
				{
   
					printf("链表未初始化\n");
				} 
				system("pause");
				break;

求指定元素的位序

求位序,我们就要定义一个position,通过遍历结点,找到与elem相等的位置,返回该位序。当position等于1时,p指向第一个结点,判断,若不等,则指向第二个结点,position+1;直到找到position,返回position即可。

Status LocateElem(LinkList L,Elemtype elem)
{
   
	Elemtype position=1;
	LinkList p;
	p=L->next;
	while(p)
	{
   
		if(elem==p->data)
		   break;
		p=p->next;
		position++;   
	}
	return position;
}

调用

case 6:
			    if(flag!=0)
				{
   
					printf("请输入你所查找的元素\n");
					scanf("%d",&elem);
					position=LocateElem(L,elem);				
					if(position>ListLength
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值