文章目录
前言
最近在学习数据结构,学到了链表,然后检验下自己,写了基本操作的完成,主要依据严蔚敏版数据结构教材以及王道数据结构考研辅导书。
提示:以下是本篇文章正文内容,下面案例可供参考
一、基本操作
printlist(linklist l); //单链表的遍历
createlist_h(linklist& l, int n); //创建单链表(头插法)
createlist_r(linklist& l, int n); //创建单链表(后插法)
initlist(linklist& l); //初始化单链表
listempty(linklist l); //判断是否为空表
destroylist_l(linklist& l); //销毁单链表
clearlist(linklist& l); //清空单链表
lengthlist_l(linklist l); //计算单链表长度
getelem(linklist& l, int i, elemtype& e); //单链表的取值
locateelem(linklist l, elemtype e); //单链表的查找
listinsert(linklist& l, int i, elemtype e); //单链表的插入
listdelete(linklist& l, int i); //单链表的删除
二、代码实现
1.代码
这是test.c部分主要是main函数的部分
#include "test.h"
//单链表的查看
void printlist(linklist l);
//创建单链表(头插法)
void createlist_h(linklist& l, int n);
//创建单链表(后插法)
void createlist_r(linklist& l, int n);
//判断创建是否成功
void create(linklist &l);
//初始化单链表
status initlist(linklist& l);
//判断是否为空表
int listempty(linklist l);
//销毁单链表
status destroylist_l(linklist& l);
//清空单链表
status clearlist(linklist& l);
//计算单链表长度
int lengthlist_l(linklist l);
//单链表的取值
void get(linklist& l);
bool getelem(linklist& l, int i, elemtype& e);
//单链表的查找
void locate(linklist l);
int locateelem(linklist l, elemtype e);
//单链表的插入
void insert(linklist& l); //判断插入是否成功
status listinsert(linklist& l, int i, elemtype e);
//单链表的删除
void delete_elem(linklist& l);
bool listdelete(linklist& l, int i);
void menu()
{
cout << "------单链表的各个操作--------" << endl;
cout << "----------请选择--------------" << endl;
cout << "------1、创建 2、插入------" << endl;
cout << "------3、删除 4、查找------" << endl;
cout << "------5、清空 6、取值------" << endl;
cout << "------7、显示 0、退出------" << endl;
}
int main()
{
linklist l;
initlist(l);
int n = 0;
int i = 0;
do{
cout<< endl;
menu(); //菜单
cin >> n;
switch (n)
{
case 1:
create(l);
break;
case 2:
insert(l);
break;
case 3:
delete_elem(l);
break;
case 4:
locate(l);
break;
case 5:
i = clearlist(l);
if (i)
{
cout << "清空成功" << endl;
}
break;
case 6:
get(l);
break;
case 7:
printlist(l);
break;
case 0:
cout << "退出" << endl;
break;
default:
cout << "输入错误" << endl;
break;
}
} while (n);
}
这是linklist.c部分主要是函数体内容的部分
#include "test.h"
void printlist(linklist l)
{
lnode* p = l->next;
while (p)
{
cout << p->data <<'\t'; //打印内容
p = p->next; //指向下一个结点
}
}
status initlist(linklist& l)
{ //构造一个空的单链表
l = new lnode; //也可以是l = (*linklist)malloc(sizeof(lnode));生成新结点作为头结点,用头指针l指向头结点 //动态分配一个linklist类型lnode大小的空间给l
l->next = NULL; //头结点的指针域置空
return ok;
}
int listempty(linklist l)
{//链表中无元素称为空链表(头指针和头结点仍在)
if (l->next)
return 0; //如果不为空返回0
else
return 1;
}
void destroylist_l(linklist& l)
{//从头指针开始,依次释放所有结点
lnode* p; //定义一个指向结点的指针p
while (l) //当l的指针不为空时
{
p = l; //l的地址给p
l = l->next; //l指向下一个结点
delete p; //删除p指针
}
}
status clearlist(linklist& l)
{//依次释放所有结点,并将头结点指针域置空
lnode* p, * q; //创建指向头结点的指针p,q
p = l->next; //下一结点的地址赋值给p
while (p) //当p不为空时
{
q = p->next; //p的下一个结点的地址赋给q
delete p; //删除p
p = q; //q的地址赋给p
}
l->next = NULL; //头结点指针域置空
return ok;
}
int lengthlist_l(linklist l)
{//从首元结点开始,依次计数所有结点
int i = 0;
lnode* p; //创建指向头结点的指针p
p = l->next; //头结点的指针域赋值给p
while (p) //当p不为空时
{
i++; //计数
p = p->next; //指向下一个结点
}
return i;
}
status getelem(linklist& l, int i, elemtype& e)
{//在带头结点的单链表l中根据序号i获取元素的值,用e返回l中第i个元素的值(返回地址)
int j = 1; //计算j
lnode* p; //创建指向头结点的指针p
p = l->next; //头结点的指针域赋值给p
while (p && j < i) //当p不为空和j不小于i时
{
p = p->next; //p指向下一个结点
j++; //计数++
}
if (!p || j > i) //如果p为空或者j>i时
return error;
e = p->data; //p指向的结点的数据域赋值给e
return ok;
}
void get(linklist& l)
{
int e ,place= 0;
cout << "请输入要取值的位置" << endl;
cin >> place;
bool flag = getelem(l, place, e);
if (flag)
{
cout << "你所取的值为" << e << endl;
}
else
{
cout << "取值不规范" << endl;
}
}
int locateelem(linklist l, elemtype e)
{
lnode* p;
int j = 1;
p = l->next;
while (p && p->data != e)
{
p = p->next;
j++;
}
if (p) return j;
else return error;
}
void locate(linklist l)
{
int e = 0;
cout << "请输入要查找的位置" << endl;
cin >> e;
int place = locateelem(l,e);
if (place)
{
cout <<"你要找的值在第" << place <<"个位置" << endl;
}
else
{
cout << "找不到你要找的值" << endl;
}
}
//lnode* locateelem(linklist l, elemtype e)
//{//在带头结点的单链表l中查找值为e的元素
// lnode* p; //创建指向头指针的p指针
// p = l->next; //下一结点的地址赋值给p
// while (p && p->data != e) //判断条件为p不为空或者数据域不等于e
// {
// p = p->next; //往下一个结点寻找
// }
// return p; //返回p的地址
//}
bool listinsert(linklist& l, int i, elemtype e)
{//在带头结点的单链表l中第i个位置插入值为e的新结点
lnode* p; //创建指向头指针的p指针
p = l;
int j = 0;
while (p && (j < i - 1)) //判断条件p不为空,j定位在插入元素下标前
{
p = p->next; //往下寻找
j++;
}
if (!p || (j > i - 1)) //!p表示i>n+1已经超过链表的长度了,j>i-1表示i<1了
{
return false;
}
lnode* s = new lnode; //建立新的结点
s->data = e; //给新结点的数据域赋值
s->next = p->next; //本来p指向下一个结点的地址给s指向下一个结点的
p->next = s; //s的地址给p指向下一个结点的
return true;
}
void insert(linklist& l)
{
int place, e = 0;
cout << "请输入要插入的位置和值" << endl;
cin >> place >> e;
bool flag = listinsert(l, place, e);
if (flag)
{
cout << "插入成功" << endl;
printlist(l);
}
else
{
cout << "插入失败" << endl;
}
}
bool listdelete(linklist& l, int i)
{
lnode* q, * p; //创建指向头指针的p指针和q指针
p = l;
int j = 0;
while (p->next && (j < i - 1)) //判断条件p不为空,p和j定位在插入元素下标前
{
p = p->next; //p指向下一个结点
j++;
}
if (!(p->next) || (j > i - 1)) //!p->next表示i>n已经超过链表的长度了,j>i-1表示i<1了
{
return false;
}
q = p->next; //让q去下一个结点
p->next = q->next; //p指向的下一个结点是q的下一个结点
delete q; //删除q
return true;
}
void delete_elem(linklist& l)
{
int place = 0;
cout << "请输入你要删除的位置" << endl;
cin >> place;
bool flag = listdelete(l, place);
if (flag)
{
cout << "删除成功" << endl;
printlist(l);
}
else
{
cout << "删除失败" << endl;
}
}
void createlist_h(linklist& l, int n)
{
initlist(l); //初始化单链表
for (int i = 0; i < n; i++) //根据链表长度n
{
lnode* p = new lnode; //创建新结点
cin >> p->data; //给新结点输入数据域
p->next = l->next; //把p->next置空
l->next = p; //头指针l的下结点是p
}
}
bool createlist_r(linklist& l, int n)
{//正位序输入n个元素的值,建立带表头结点单链表l
initlist(l); //初始化单链表
clearlist(l); //清空单链表
lnode* r = l; //尾指针r指向头结点
for (int i = 0; i < n; i++) //根据链表长度n
{
lnode* p = new lnode; //创建新结点
cin >> p->data; //给新结点输入数据域
p->next = NULL; //把p->next置空
r->next = p; //p的地址赋给r的指针域
r=p; //把r看作p
}
return true;
}
void create(linklist &l)
{
int n = 0;
cout << "请输入要创建的单链表的长度" << endl;
cin >> n;
bool flag = createlist_r(l, n);
if (flag)
{
cout << "创建成功" << endl;
printlist(l); //显示当前单链表内容
}
else
{
cout << "创建失败" << endl;
}
}
这是test.h的部分,主要是头文件的部分
//头文件的包含
#include <iostream>
#include <stdlib.h>
using namespace std;
//符号的定义
#define status int
#define ok 1
#define error 0
#define elemtype int
//链表的存储结构
typedef struct lnode
{
elemtype data; //结点的数据域
struct lnode* next; //结点的指针域
}lnode, * linklist; //linklist为指向结构体lnode的指针类型
2.显示效果
总结
实现代码和看懂代码区别还是很大的,细节决定成败,写代码的习惯很能决定你的高度,并且决定你的正确率,在写的过程中出错了千万不要烦躁,冷静去分析,层层剖析,主要还是要冷静,不要砸电脑,写出程序后,这并不是我成功了,我警告还有32个哈哈哈,所以还需要去完善代码的健壮性,并且单链表用到了大量的指针,我是很慌的,指针的错误是隐式的,很难察觉,用的时候千万小心,关于指针我推荐一本书,你们肯定知道,不知道最好,不然我白写了《c和指针》很不错的一本书。我还在不断提升,一起努力吧,hh~~