实验目的:
1、掌握线性表的链式存储结构的表示与实现。
2、掌握和验证单链表上各类操作的实现方法。
3、掌握C++编程中的一些基本编程规范。
实验要求:
实现单链表的基本操作
1)构造空的单链表;
2)建立含有若干数据元素的单链表并输出;
3)求表长;
4)获取第三个元素的值;
5)在第四个位置后,插入一个值为“38”的新的元素后输出单链表;
6)删除第五个位置上的元素后输出单链表;
测试数据:23 33 21 45 67 98
下面就以本次实验来讲解单链表操作的实现:
一、首先需要自定义一个结点类型的结构体:
struct LNode{
int data; //数据域
struct LNode* next; //指针域
}LNode, *LinkList;
二、实现单链表的创建,并且初始化,这里使用的是尾插法:
void Init(struct LNode* L) { //创建并且初始化链表
int cur;
cout<<"请输入数据并且以-1结束:";
cin >> cur;
while (cur != -1) {
struct LNode* ptr = (struct LNode*)malloc(sizeof(struct LNode)); //使用malloc()函数为ptr申请空间
ptr->data= cur;
ptr->next = NULL;
L->next = ptr;
L = L->next;
cin >> cur;
}
}
三、实现链表的遍历
void Show(struct LNode* L) { //遍历链表值
cout << "链表遍历:" ;
while (L->next) {
cout << L->next->data << " ";
L = L->next;
}
cout << endl;
}
四、求链表的长度
int lengthList (struct LNode* L) { //求链表长度
int len = 0;
while (L->next) {
len ++;
L = L->next;
}
return len;
}
或者这里也可以是一个没有返回类型的函数,代码如下:
void lengthList (struct LNode* L) { //求链表长度
int len = 0;
while (L->next) {
len ++;
L = L->next;
}
cout<<"链表的长度为:"<<len;
}
五、实现数据的插入,在第k个位置插入数据,数据值为n
void InsertList (struct LNode* L, int k, int n) {
struct LNode* pre = NULL; //存储第K-1个元素的值
struct LNode* ptr = (struct LNode*)malloc(sizeof(struct LNode)); //申请空间
ptr->data = n;
ptr->next = NULL;
while (k && L->next) { //查找到放置data元素的位置
pre = L;
L = L->next;
k --;
}
if (k > 0) { //如果K > 0 直接插到链表的表尾
L->next = ptr;
L = L->next;
}else {
pre->next = ptr; //链接链表
ptr->next = L;
}
}
六、实现数据的删除,数据的删除有两种实现方法
(一)是按照位置删除数据,删除第k个位置的元素
void DeleteList_Position(struct LNode* L, int k) { //删除第K个位置的结点
if (lengthList(L) <= 0) {
cout << "表空,没有元素可删除" << endl;
return;
}
struct LNode* ptr = L->next;
struct LNode* pre = L; //记录ptr的前一个位置的结点
k = k - 1; //因为如果k = 1,直接用pre->next = ptr->next就把ptr删掉了,所以要减1
while (k-- && ptr) {
pre = ptr;
ptr = ptr->next;
}
if (ptr == NULL || k > 0) {
cout << "要删除的位置不存在" << endl;
}else {
pre->next = ptr->next; //删除ptr结点
free(ptr); //释放空间
}
}
(二)是按照值来删除数据,删除值为x的元素
void DeleteList (struct LNode* L, int x) { //删除值为x的结点(链表无重复值)
if (lengthList(L) <= 0) {
cout << "表空,没有元素可删除" << endl;
return;
}
struct LNode* ptr = L->next;
struct LNode* pre = L; //记录ptr的前一个位置的结点
while (ptr) {
if (ptr->data == x) {
pre->next = ptr->next; //把x值的结点的前一个结点的next指向ptr的next结点
free(ptr); //释放空间
return;
}
pre = ptr;
ptr = pre->next;
}
}
有没有小伙伴发现这段代码有一个缺陷,就是如果按照值删除的话,链表中的元素是不能够有重复的元素的,如果有重复的元素,就默认删除第一个出现该值得元素。
七、获取链表中某个元素的值
int GetElemList(struct LNode* L, int i) { //返回第i个位置的值
struct LNode* ptr = L;
int k = i; //标记i的值,以防不存在输出显示
while (i > 0 && ptr->next) {
ptr = ptr->next;
i --;
}
if (i == 0 && ptr != NULL) { //当i == 0 和 ptr 不为空代表找到了第i个位置的元素
return ptr->data;
}else {
cout << "第" << k << "个位置不存在" << endl;
return -1;
}
}
上面代码就是实现了链表操作的各种功能,下面是主函数:
/*实现单链表的基本操作
1)构造空的单链表;
2)建立含有若干数据元素的单链表并输出;
3)求表长;
4)获取第三个元素的值;
5)在第四个位置后,插入一个值为“38”的新的元素后输出单链表;
6)删除第五个位置上的元素后输出单链表;*/
void main() {
struct LNode* head = (struct LNode*)malloc(sizeof(struct LNode)); //头结点(不存值)
head->next = NULL;
cout<<"表长为:"<<lengthList(head)<<endl;//求表长;
GetElemList(head, 3);//获取第三个元素的值
Show(head);//后输出单链表
InsertList(head, 5, 38);//在第四个位置后,插入一个值为“38”的新的元素
Show(head);//输出单链表
DeleteList_Position(head, 5);//删除第五个位置上的元素
Show(head);//输出单链表
}
以上就是单链表的算法实现,单链表的实现方式十分灵活,有多种实现方法,但是在数据结构上都十分相似。上述代码仅是个人学习中的总结,如有不足之处,请指正批评~~