数据结构单链表
刚刚接触数据结构的我也是一脸懵逼的看待单链表,数组向线性表的思想和代码的突然转换有点蒙逼,尤其是为什么要创建结构体,单链表的实现首先要创建一个结构体,结构体的作用就是把一个数据和下个数据的物理地址绑在一起形成单链表的一个元素(数据+下个数据的地址)
数据 | 下个元素的地址 |
---|
单链表的代码
闲着没事敲的代码不是很完美,也没有按照书上的来,但是应付老师的作业估计没有啥大问题
#include <iostream>
#include <malloc.h>
using namespace std;
typedef char ElemType;
typedef struct LNode//单链表结构体
{
ElemType data;
struct LNode *next;
}LinkNode;
void InitList(LinkNode *&L)//初始化单链表分配空间
{
L=(LinkNode *)malloc(sizeof(LinkNode));
L->next=NULL;
}
void CreateListR(LinkNode *&L,ElemType a[],int n)//创建单链表
{
LinkNode *s,*r;
r=L;
for(int i=0;i<n;i++)
{
cin>>a[i];
s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=a[i];
r->next=s;
r=s;
}
r->next=NULL;
}
void DispList(LinkNode *L)//输出单链表函数
{
LinkNode *p=L->next;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
bool ListEmpty(LinkNode *L)//判断单链表是否为空
{
return(L->next==NULL);
}
void GetElem(LinkNode *L,int n)//取出单链表某元素
{
LinkNode *p=L->next;
int i=1;
ElemType e;
while(p!=NULL)
{
if(i==n)
{
e=p->data;
break;
}
p=p->next;
i++;
}
if(p!=NULL)//判断输入是否合法
cout<<endl<<"单链表中第"<<n<<"个元素为:"<<e<<endl;
else
{
cout<<endl<<"输入越界不合法请重新输入:";
cin>>n;
GetElem(L,n);
}
}
void LocateElem(LinkNode *L,ElemType e)//得到单链表中某元素的位置
{
int i=1;
LinkNode *p=L->next;
while(p!=NULL)
{
if(e==p->data)
{
if(p->next!=NULL)
{
p=p->next;
}
break;
}
p=p->next;
i++;
}
if(p!=NULL)//判断输入元素是否在该单链表中
cout<<endl<<e<<"元素在该单链表中的位置为:"<<i<<endl;
else
{
cout<<"您输入的元素不属于该单链表"<<endl<<endl<<"请重新输入:";
cin>>e;
LocateElem(L,e);
}
}
void ListInsert(LinkNode *&L,int n,ElemType e)//在单链表中指定位置插入某元素
{
int i=1;
LinkNode *s,*p=L;
while(p!=NULL)//p为空循环结束
{
if(i==n)
{
s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=e;
s->next=p->next;
p->next=s;
}
i++;
p=p->next;
}
}
void ListDelete(LinkNode*&L,int n)//删除单链表中指定位置的元素
{
int i=1;
LinkNode *q,*p=L;
while(p!=NULL)
{
if(i==n)
{
q=p->next;
p->next=q->next;
free(q);
break;
}
i++;
p=p->next;
}
}
int main()
{
int n,x;
ElemType a[100],e;//创建数组
cout<<"请输入数组长度:";
cin>>n;
LinkNode *L;//结构体指针
cout<<endl<<"单链表初始化中. . ."<<endl<<endl;
InitList(L);//初始化单链表
cout<<"单请输入链表元素:";
CreateListR(L,a,n);//创建单链表
cout<<endl<<"单链表创建成功. . ."<<endl<<endl<<"单链表为:";
DispList(L);//输出单链表
cout<<endl<<"单链表的长度为:"<<n<<endl;
if(ListEmpty(L))//判断单链表是否为空
cout<<endl<<"单链表为空"<<endl;
else
cout<<endl<<"单链表不为空"<<endl;
cout<<endl<<"请输入所取元素在单链表的逻辑位置:";
cin>>x;
GetElem(L,x);//取出指定位置的元素
cout<<endl<<"请输入想要获取元素位置的元素:";
cin>>e;
LocateElem(L,e);//取出单链表指定元素的位置
cout<<endl<<"请输入想要插入元素的位置:";
cin>>n;
cout<<endl<<"请输入想要插入的元素:";
cin>>e;
ListInsert(L,n,e);//在单链表中指定位置插入元素
cout<<endl<<"插入元素后的单链表为:";
DispList(L);//输出单链表
cout<<endl<<"请输入想要删除元素的位置:";
cin>>n;
ListDelete(L,n);//删除单链表中指定位置的元素
cout<<endl<<"删除元素之后的单链表为:";
DispList(L);//输出单链表
// free(L);//释放单链表的内存空间:错误,应用循环释放;
return 0;
}
修改
main函数的最后一行free(L);如果这样写的话只是释放了头结点的空间,虽然当你再次调用输出函数DispList(L)时结果出现乱码,那是因为只是把头结点的删除了导致整个单链表找不到而发生的乱码,实际上你单链表所占的内存空间是没有释放的只是你找不到了
所以你想要的释放整个单链表的空间就要像建立单链表一样用一个循环进行操作具体怎样删除的算法,和插入与删除的算法基本思想一样,这里就不在唠叨了