实验二 链表
本次继续更新数据结构与算法这门课的上机实验,主要涉及链表这一数据结构。
特此感谢, 实验过程中邓老师的指导和帮助!
对于想要获取此实验报告和源代码的同学,欢迎光顾小生寒舍 GitHub:https://github.com/ChromeWei?tab=repositories
实验内容:
一、参考教材,编写链表的相关程序(定义,初始化,插入,删除,取值,赋值等等)
二、编写main函数,利用已有函数,构造一个数据元素值依次为1-50的链表,并逐个输出,即输出1,2,3……49,50。
三、编写函数,将表倒序,并在main函数中调用,再次输出,也就是输出50,49,48……2,1。(如果需要得到表长,另外编写函数实现。)
四、说明你的倒序程序的时间复杂度是多少?用O(f(n))表示。
附件: 源代码
测试环境:Win10,Dev-C++
#include "iostream"
#include "stdlib.h"
using namespace std;
#define ElemType int
#define OVERFLOW 1
#define Status bool
#define OK true
#define ERROR false
#define N 50
typedef struct LNode {
ElemType data; // 数据域
struct LNode *next; // 指针域
} LNode, *LinkList;
Status Init_List(LinkList& L)//先建立一个带头结点的空单链表
{
L = (LinkList)malloc(sizeof(LNode));
if ( L == NULL) return ERROR;
L->next = NULL;
return OK;
}
Status GetElem_L(LinkList& L, int i, ElemType &e) {
// L是带头结点的链表的头指针,以e返回第i个元素
LinkList p = L->next; int j = 1; // p指向第一个结点,j为计数器
while (p && j<i) { p = p->next; ++j; }// 顺指针向后查找,直到p指向第i个元素或p为空
if ( !p || j>i )
return ERROR; // 第 i 个元素不存在
e = p->data; // 取得第 i 个元素
return OK;
} // GetElem_L
Status SetElem_L(LinkList& L, int i, ElemType e) {
// L是带头结点的链表的头指针,让第i个元素等于e
LinkList p = L->next; int j = 1; // p指向第一个结点,j为计数器
while (p && j<i) { p = p->next; ++j; }// 顺指针向后查找,直到p指向第i个元素或p为空
if ( !p || j>i )
return ERROR; //第i个元素不存在
p->data=e; //取得i个元素
cout<<"Good!"<<endl;
return OK;
} // GetElem_L
Status ListInsert_L(LinkList& L, int i, ElemType e) {
//L为带头结点的单链表的头指针,本算法在链表中第i个结点之前插入新的元素e,i等于1表示插入第1个元素,i等于表长加1表示插入在最后。
if(i<1)
return ERROR;
LinkList p = L; int j = 0;
while (p->next && j < i-1)
{ p = p->next; ++j; } //寻找第i-1个结点
if (j<i-1)
return ERROR; // i大于表长
LinkList s = (LinkList) malloc (sizeof(LNode)); //生成新结点
if ( s == NULL) return ERROR;
s->data = e;
s->next = p->next;
p->next = s; // 插入L中
return OK;
} // LinstInsert_L
Status ListDelete_L(LinkList& L, int i, ElemType &e) {
//删除以L为头指针(带头结点)的单链表中第i个结点
if(i<1)
return ERROR;
LinkList p = L; int j = 0;
while (p->next && j < i-1)
{ p = p->next; ++j; }//寻找第i个结点,并令p指向其前趋
if (!(p->next))
return ERROR; // 删除位置不合理
LinkList q = p->next; p->next = q->next; //删除并释放结点
e = q->data; free(q);
return OK;
} // ListDelete_L
Status List_Invert(LinkList& L){
//链表倒序1:每个元素的指针倒向,相许过程见图示
if(NULL == L || NULL == L->next ) return ERROR;//空链表和只有一个元素的链表不做处理
//NULL == L->next->next时,有两个元素的链表也是特殊的,本程序能解决
LinkList p1,p2,p3;//指向需要交换顺序的元素的指针,最少需要三个指针
p1 = L->next;
p2 = p1->next;
p3 = p2->next;
p1->next = NULL;
while(p3)
{
p2->next = p1; //任意中间段链表,第二个元素指向前一个
p1 = p2;//指针往下一个元素移动
p2 = p3; //同上
p3 = p3->next;//用于判断下一个是否为NULL
}
//循环结束时,p3指向NULL,p2指向最后一个元素
p2->next = p1; //最后两个元素倒序
L->next = p2; //头结点指向新的链表第一个元素
return OK;
}
void daoxu(LinkList& L){
//链表倒序2: 在L的头结点出进行删除,同时在L2头结点处进行插入操作
int e;
LinkList L2;
if(!Init_List(L2)) return ;//L2链表未初始化成功
while(ListDelete_L(L, 1, e)) //删除L链表中的元素,并用e存储
ListInsert_L(L2, 1, e);
free(L); //free掉的只是指向的内容,指针本身没被释放掉
// free(L);L = L2;这两条语句先后顺序没有要求
L = L2;//原头结点指向新的链表头结点
}
void myprint(LinkList& L){
//输出链表
LinkList p = L;
while(p=p->next)
cout<<p->data<<" ";
cout<<endl;
}
int main()
{
LinkList myl;
ElemType i;
if(!Init_List(myl)) return 0;//建立链表
for( i = 1; i <= N; i++)
ListInsert_L(myl, i, i); //产生1~50的顺序链表
myprint(myl);
//List_Invert(myl); //倒序
daoxu(myl);
myprint(myl);
return 0;
}
上一篇:数据结构与算法上机实验一 顺序表
下一篇:数据结构与算法上机实验三 队列
欢迎各位订阅我,谢谢大家的点赞和专注!我会继续给大家分享我大学期间详细的实践项目。
知识星球
专为求职面试中算法与数据结构的小伙伴,创了学习交流/刷题群(知识星球)!想要最快的提升算法与数据结构技能,和更多小伙伴一起来吧!
进群获取互联网大厂高频coding题库,告别刷题400道,分类整理的题库,算法思路和源代码实现配套,各个类型总结出来的解题模板,远比你一个人要强!
MaiweiAI-com | WeChat ID: Yida_Zhang2
机器学习+计算机视觉