单链表介绍
-
线性表的链式存储结构的特点在于它可以使用一组任意的存储单元存储数据,在插入和删除的操作中不需要移动相应的元素,只需要更改相应的指针即可。
-
这次实现的是线性表的单链表表示。单链表中的数据元素不仅要存储自身元素,还要存储一个其后继元素的位置,这两部分信息组成的一个存储映像,称为结点。结点由两部分组成:数据域和指针域,如下所示:
-
链表的第一个结点称为头结点,头结点的数据域可以不存信息,也可以将当前链表的长度存入,随意。但是整个链表的存取必须是从头结点开始,这点是硬性要求。
注:图片是百度图片搜索得到,如有侵权,请联系删除
-
在实现过程中由于指针的错误使用,出现了很多问题,例如:越界(访问结点不存在或逆向访问时访问到了头结点的数据域)
实现功能
关于实现的功能,我选择的是常用的几个功能,一些不是必要的功能选择了放弃,具体实现功能如下:
- 创建一个具有 n 个有效结点的链表
- 删除链表中第 i 个结点,并返回其数据值
- 获取链表中第 i 个结点的数据
- 在链表中第 i 个位置插入指定值
- 返回链表的长度
- 删除链表
代码实现
#include<stdio.h>
#include<iostream> //由于使用scanf时出现了类型等问题,就使用了C++的输入和输出
#include<stdlib.h> //malloc的头文件
#define ElmeType int
typedef struct Lnode //创建单链表的存储结构
{
ElmeType data; //数据域
struct Lnode *next; //指针域
}Lnode,*LinkList;
ElmeType CreateList_L(LinkList &L, ElmeType n)
//创建一个单链表,n个存储数据结点
{
LinkList p;
L = (LinkList)malloc(sizeof(Lnode)); //创建新结点
L->next = NULL; //将头结点的指针域置NULL
for (ElmeType i = 0; i < n; i++) //利用循环将数据输入结点中
{
p = (LinkList)malloc(sizeof(Lnode));
std::cin >> p->data;
p->next = L->next; //移动到下一个结点
L->next = p;
}
return 0;
}
ElmeType ListDelete_L(LinkList &L, ElmeType i, ElmeType &e)
//删除链表中第i个元素,并通过e返回其值
{
LinkList p = L , q; //创建两个临时结点
ElmeType j = 0; //j为计数器
while (p->next && j < i - 1 )
{
p = p->next;
++j;
} //移动到删除的结点
if (!(p->next) || j < i - 1) //检查删除位置是否合法
return -1;
q = p->next;
p->next = q->next;
e = q->data; //返回删除元素
free(q);
return 0;
}
ElmeType GetElme_L(LinkList L, ElmeType i, ElmeType &e)
//返回链表中第i个元素
{
LinkList p = L->next;
ElmeType j = 0;
while (p && j < i)
{
p = p->next;
++j;
}//移动到相应结点
if (!p || j > i)
return -1;
e = p->data;
return 0;
}
ElmeType ListInsert_L(LinkList &L, ElmeType i, ElmeType e)
//在链表的第i个位置插入值e
{
LinkList p = L;
ElmeType j = 0;
while (p->next && j < i - 1)
{
p = p->next;
++j;
}
if (!(p->next) || j > i - 1)
return -1;
LinkList r = (LinkList)malloc(sizeof(Lnode));
r->data = e;
r->next = p->next;
p->next = r;
return 0;
}
ElmeType ListLength_L(LinkList L, ElmeType &n)
//返回链表的长度
{
LinkList r = L;
ElmeType i = 0;
while (r->next)
{
i += 1;
std::cout << "执行" << std::endl;
r = r->next;
}
n = i;
return 0;
}
ElmeType DestroyList_L(LinkList &L)
//删除链表
{
free(L);
return 0;
}
ElmeType main()
{
LinkList S;
ElmeType i , n , e;
CreateList_L(S, 10);
for (i = 0; i < 12; i++)
{
GetElme_L(S, i, n);
std::cout<<n<<std::endl;
}
ListDelete_L(S, 5, e);
std::cout<<"删除的元素:" << e<<std::endl;
for (i = 0; i < 9; i++)
{
GetElme_L(S, i, n);
std::cout << n << std::endl;
}
ListInsert_L(S, 1, 0);
for (i = 0; i < 10; i++)
{
GetElme_L(S, i, n);
std::cout << n << std::endl;
}
ListLength_L(S, n);
std::cout << "链表的长度为:" <<n << std::endl;
return 0;
}