【C/C++数据结构实验】-实验3.链表基本操作的实现

  • Post author:
  • Post category:其他


引言

【C/C++数据结构实验】这个系列是我这个学期上的数据结构课上老师布置的实验,实验题目如下。我一般用c++,但是没有用到类啥的,就是普普通通的面向过程的思想不是面向对象的思想,只是借用c++的一些方便的环境,比如形参处可以写——*&,引用型参数很好用。

有需要的同学们自取吧,虽然算法不是很巧妙,但是都是我实实在在学完了自己一点点写出来的,运行结果是完全没问题的。正好这门课结课了,发上来我也能再复习一下!

一、实验题目


上机实验题3:

链表基本操作的实现

建立单链表存储数据(10,20,30,40,50,60,70,80,90,100),要求:

(1)头插法或尾插法建立单链表,并输出单链表中所有元素;

(2)输出单链表中的最大值和最小值;

(3)键盘输入一个值x,输出链表中第一个值为x的元素的位序;

(4)键盘输入一位序值b,在第b个元素之前插入值为500的元素,输出链表中的所有数据;

(5)键盘输入位序值m,删除位序为m的元素,输出链表中的所有数据;

(6)输出单链表的长度。


(要求尽量将每一个操作模块化,可以将链表头指针设置成全局变量,也可以采用引用型参数。)

二、实验具体算法(c++)

#include<iostream>
#include<cstdlib>
#define MaxSize 50
using namespace std;
typedef int ElemType;
//声明LinkNode类型
typedef struct LNode{
	ElemType date;//存放元素值
    struct LNode *next;//指向后继节点的指针域
}LinkNode;
//建立单链表,头插法
void CreateListR(LinkNode *&L,ElemType a[],int n)
{int i=0;
L=(LinkNode*)malloc(sizeof(LinkNode));
L->next=NULL;//建立单链表并且为其初始化,将其next域置零
LinkNode *p;
while(i<=n)
{  
  p=(LinkNode*)malloc(sizeof(LinkNode));//为每一个a[i]对应的数值建立一个新的结点,将a[i]的数值赋给这个新的结点
  p->date=a[n-i];
  p->next=L->next;//将p所指的结点插入到L链表的头节点之后的首节点位置
  L->next=p;
  i++;
}
}
//比较大小
void MaxMin(LinkNode *L)
{int max,min;
max=L->next->date;
min=L->next->date;
LinkNode *p=L->next;//p指向L链表的首节点
while(p->next!=NULL)
    {
	if(max<p->date)
		max=p->date;
	if(min>p->date)
		min=p->date;
	    p=p->next;
	}
cout<<"max="<<max<<";min="<<min<<endl;
}
//输出链表
void DispList(LinkNode *&L)
{
	LinkNode *p=L->next;//p指向首结点
	while(p->next!=NULL)
	{
	cout<<p->date<<" ";
	p=p->next;//p指向L的下一个结点
	}
	cout<<endl;
}
//向链表中插入元素
bool ListInsert(LinkNode *&L,ElemType e,int i)
{int j=0;
	LinkNode *s,*p=L->next;
	if(i<1)
	{cout<<"插入位序不合理!"<<endl;//注意,插入函数内的if语句必须要保证:符合if语句条件,输出相应的信息后就结束,不再执行其后续语句,否则会顺序执行下面的语句。可以定义函数为bool型,在每个if语句后执行相应的return(可以在return前正常输出提示信息,而让return只起到符合语句就推出插入函数的作用)。但是一定不能采用break语句,否则还是会继续(也可能break不合理无法运行) 
	 return false;
	}
	while(p!=NULL&&j<i-1)//注意:链表无需注意该结点的下一个是否为空!!!!!只需要保证本结点不为空,就可以在本结点之前插入元素(链表存储空间不连续)
	{
		p=p->next;
		j++;
	}
	if(p==NULL)
	{
		cout<<"第"<<i-1<<"个结点为空结点,第"<<i<<"个结点超出链表范围,无法插入!"<<endl;
	     return false;
	}
	else
	{	s=(LinkNode*)malloc(sizeof(LinkNode));
	    s->date=e;
		s->next=p->next;
		p->next=s;
		cout<<"插入成功!"<<endl;
		return true;
	}
}
//删除链表某位序对应的元素
bool ListDelect(LinkNode *&L,int i)
{
	LinkNode *s,*p=L->next;//p指向L首结点
	if(i<1)
	{
	cout<<"位序错误!"<<endl;
	return false;
	}
	int j;
	for(j=1;p!=NULL&&j<i-1;j++)//初始p指向首节点,即链表中第一个元素,故初始j=1。j的数值对应链表中元素位序(逻辑位序)
		p=p->next;
	if(p==NULL)
	{
		cout<<"给出的位序超出链表元素最大位序,不存在该结点,无法删除!"<<endl;
		return false;
	}
	else
	{   
		s=p->next;//!!!此步非常关键,如果不把第i个指针存起来,在删除时,无论是先连接还是先free都会出现问题——丢失掉第i个结点后续的结点
		p->next = s->next;
		free(s);//释放掉第i个结点
	}
}
//按元素查找
void LocateList(LinkNode *L,ElemType e)
{
int i;
LinkNode *p=L->next;
for(i=1;p!=NULL&&p->date!=e;i++)//由于此处的p是指针,且没有为其分配内存空间,故p为纯指针,p表示指针p(所指向的值)的地址
   p=p->next;
if(p==NULL)
	cout<<"不存在数值"<<e<<",查找失败!"<<endl<<endl;
else
	cout<<"查找成功,该元素位序为:"<<i<<endl<<endl;//注意,一般将最后的成功的结果的条件放在最后面。“先排除所有错误的情况,剩下的就是正确的结果!!!”
}
//返回链表长度
int ListLength(LinkNode *&L)
{
	LinkNode *p=L->next;
	int i=1;
	while(p->next!=NULL)
	{
		p=p->next;
		i++;
	}
		return i;
}
//销毁链表
void DestroyList(LinkNode *&L)
{
	LinkNode *p=L,*s=L->next;
	while(s->next!=NULL)
	{
	   free(p);
	   p=s;
	   s=s->next;
	}
	free(s);
	cout<<endl<<"链表销毁成功!"<<endl<<endl;
}
int main()
{
	LinkNode *m;
	int x,b,k,a[MaxSize];
	for(int i=0;i<10;i++)
	a[i]=(i+1)*10;
	CreateListR(m,a,10);
	cout<<"(1)输出链表:"<<endl;
	DispList(m);
	cout<<endl<<"(2)链表中最大元素与最小元素:"<<endl;
	MaxMin(m);
	cout<<endl<<"(3)将查找链表中第一个值为x的元素的位序,请输入值x:";
	cin>>x;
	LocateList(m,x);
	cout<<"(4)将在位序b之前插入值为500的元素,请输入位序b:";
	cin>>b;
	ListInsert(m,500,b);
	cout<<"输出链表:"<<endl;
	DispList(m);
	cout<<endl<<"(5)将删除链表中位序为k的元素,请输入位序值k:";
	cin>>k;
	ListDelect(m,k);
	cout<<"输出链表:"<<endl;
	DispList(m);
	cout<<endl<<"(6)单链表长度为:"<<ListLength(m)<<endl;
	DestroyList(m);
}

三、实验总结与收获

我怕我忘了,我记性不好,所以当时把能想到的,还有我自己调出来的错误都给写在注释里了。说实话,当时写实验报告的时候,实验收获是最难写的,尤其是前几个实验没有总结的意识,导致写完程序过几天写报告的时候脑子空空如也。大家一定要想到什么就写出来,记在脑子里真的会忘的!!(也可能我是金鱼的记忆???)



版权声明:本文为bon_e_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。