关于数据结构中的链表
最近在复习数据结构,之前基本一点都没有看,算是重新开始学习
对于链表的代码实现自己又敲了一遍 。。
记录一下,欢迎大神批评指正
直接上代码
#include<bits/stdc++.h>
#define OK 1
#define ERROR 0
using namespace std;
typedef int Status;
typedef int ElemType;
//链表的定义结构
typedef struct Lnode
{
ElemType data;//结点的数据域
struct Lnode *next;//结点的指针域
}Lnode,*LinkList;
//声明结构体后紧跟着定义两个结构体变量
//Lnode 是结点变量
//LinkList 为指向结构体Lnode的指针
//单链表的初始化,用头指针L指向头结点
Status InitList_L(LinkList &L)
{
L = new Lnode;
L->next = NULL;
return OK;
}
//单链表的建立,头插法建立单链表
bool CreateList_H(LinkList &L,int n)
{
int x;
L= new Lnode;
L->next = NULL;//先建立一个带头结点的单链表
Lnode *p;
for(int i = n;i>0;i--)
{
cin >> x;
p = new Lnode;
p->data = x;
p->next = L->next;
L->next = p;
}
return true;
}
//单链表的建立,尾插法建立单链表
bool CreateList_R(LinkList &L,int n)
{
int x;
L = new Lnode;
L->next = NULL;//建立空的链表
Lnode *p;
Lnode *r;//生成一个尾指针
r = L;//尾指针指向头结点
for(int i=0;i<n;i++)
{
cin >> x;
p=new Lnode;//申请一个新的结点p
p->data = x;//将我们要保存的数据置于p的指针域
p->next = NULL;//再将p的指针域置空,因为要将它置于最后
r->next = p;//把尾结点的指针域指向p,将p结点接上
r=p;//尾结点移动到p上
}
return true;
}
// 判断链表是否为空
Status ListEmpty(LinkList L)
{
if(L->next) return 0;//非空
else return 1;
}
//单链表的销毁
Status DestroyList_L(LinkList &L)
{
Lnode *p;//指向我们当前要销毁的结点
while(L)//循环条件L!=null
{
p=L;
L= L->next;
delete p;
}
return OK;
}
//单链表的清空
Status ClearList(LinkList &L)
{
Lnode *p,*q;
p=L->next;
while(p)
{
q=p->next;
delete p;
p=q;
}
L->next= NULL;
return OK;
}
//求单链表的表长
Status ListLength_L(LinkList L)
{
Lnode *p;
int i=0;
p=L->next;
while(p)
{
i++;
p=p->next;
}
return i;
}
//单链表的取值算法-取出单链表中第i个元素的值
Status GetElem_L(LinkList L,int i,ElemType &e)
{
Lnode *p;
p=L->next;
int j=1;
while (p&&j<i)
{
p=p->next;
j++;
}
if(!p||j>i)
{
return ERROR;
}
e=p->data;
return e;
}
//单链表的按值查找-根据指定元素获取该元素所在的地址(只返回第一个找到的元素)
Lnode *LocateElem_L(LinkList L,ElemType e)
{
Lnode *p;
p=L->next;
while(p&&p->data!=e)
{
p=p->next;
}
return p;//返回的是L中值为e的元素的地址
}
//单链表的按值查找-根据指定元素获取该元素所在的位置(只返回第一个找到的元素)
int LocateELem_L(LinkList L,ElemType e)
{
Lnode *p;
int j=1;
p=L->next;//p指向首元结点
while(p&&p->data!=e)
{
p=p->next;
j++;
}
if(p) return j;
else return 0;
}
//单链表的插入操作-在第i个结点前插入值为e的新结点
//插入在第i个结点前,就作为新的第i个结点
//所以需要找第i-1个结点开始,需要利用它的指针域
Status ListInsert_L(LinkList &L,int i,ElemType e)
{
Lnode *p,*s;//指针p指向当前扫描到的结点
int j = 0;// 用j计数当前p指向的是第几个节点
p=L;//L指向头结点,P=L,且头结点是第0个结点
while(p&&j<i-1)//寻找到第i-1个结点,p指向i-1结点
{
p=p->next;
j++;
}
if(!p||i<1) return ERROR;//i大于表长+1或小于1,非法
s = new Lnode;
s->data = e;//生成新的结点s,将新节点s的数据域置于e
s->next = p->next;
p->next = s;
return OK;
}
//单链表的删除操作-将链表中的第i个元素删除
//同样找到第i-1个结点,将其指针域指向第i+1个结点,释放第i个结点
Status ListDelete_L(LinkList &L,int i/*,ElemType &e*/)
{
Lnode *p,*q;//指针p指向当前扫描的结点
int j = 0;// 用j计数当前p指向的是第几个节点
p=L;//L指向头结点,P=L,且头结点是第0个结点
while(p&&j<i-1)//寻找第i-1个结点
{
p=p->next;
j++;
}
if(!(p->next)||i<1||!p) return ERROR;//删除位置不合理
q=p->next; // 临时存储的被删除的结点以备释放
p->next = q->next;//改变被删除节点的前驱节点的指针域
//e=q->data;//用e存储被删除节点的数据域
delete q;//释放其空间
return OK;
}
//打印链表
void ListPrint_L(LinkList L)
{
cout << "当前链表为" << endl;
Lnode *p;
p=L->next;
while(p)
{
cout <<p->data << " " ;
p = p->next;
}
cout << endl;
}
// *************************************基本功能函数
// 头插法创建一个链表
void Create_H (LinkList &L)
{
int n; bool flag;
cout << "请输入你要建立的单链表的长度:";
cin >> n;
printf("请输入%d个数:",n);
flag = CreateList_H(L,n);
if(flag)
{
cout << "创建成功!"<< endl;
ListPrint_L(L);
}
else
{
cout << "创建失败"<< endl;
}
}
// 尾插法创建一个链表
void Create_R (LinkList &L)
{
int n; bool flag;
cout << "请输入你要建立的单链表的长度:";
cin >> n;
//printf("请输入%d个数:",n);
cout << "请输入"<< n <<"个数" << endl;
flag = CreateList_R(L,n);
if(flag)
{
cout << "创建成功!"<< endl;
ListPrint_L(L);
}
else
{
cout << "创建失败"<< endl;
}
}
//插入操作
void Insert (LinkList &L)
{
int place;
ElemType e;
int k;
cout << "请输入你要插入的位置及其元素:"<<endl;
cin >> place >> e ;
k = ListInsert_L(L,place,e);
if(k)
{
cout << "插入成功!";
ListPrint_L(L);
}
}
//删除操作
void Delete (LinkList &L)
{
int place;
int k;
cout << " 请输入你要删除的位置"<< endl;
cin >> place;
k = ListDelete_L(L,place);
if(k)
{
cout<< "删除成功!";
ListPrint_L(L);
}
}
//查找操作1,根据值返回其位置
void Search1 (LinkList L)
{
ElemType e;
int k;
cout << "请输入你要查找的值:"<< endl;
cin >> e;
k = LocateELem_L(L,e);
if(k)
{
cout << "该元素的位置为:"<<k<<endl;
}
else
{
cout << "未找到该元素!"<<endl;
}
}
//查找操作2,获取某一位置的值
void Search2(LinkList L)
{
int k;
ElemType e;
int place;
cout << "请输入你要获得的位置"<< endl;
cin >> place;
k = GetElem_L(L,place,e);
if(k)
{
cout << "当前位置的值为"<< k<<endl ;
}
else
{
cout << "输入非法!"<<endl;
}
}
//获取长度
void GetLength(LinkList L)
{
int k;
k = ListLength_L(L);
if(k)
{
cout << "当前链表的长度为:"<< k<< endl;
}
else
{
cout << "当前链表长度为空"<<endl;
}
}
//清空
void Empty (LinkList &L)
{
int k;
k = ClearList(L);
if(k)
{
cout << "单链表已清空"<<endl;
}
}
//判空
void IsEmpty (LinkList L)
{
int k;
k = ListEmpty(L);
if(k)
{
cout << "当前单链表为空"<< endl;
}
}
void menu()
{
cout <<"1.创建" << endl;
cout <<"2.打印" << endl;
cout <<"3.插入" << endl;
cout <<"4.删除" << endl;
cout <<"5.查找1" << endl;
cout <<"6.查找2" << endl;
cout <<"7.长度" << endl;
cout <<"8.清空" << endl;
cout <<"9.判空" << endl;
cout <<"0.退出" << endl;
}
int main()
{
LinkList L; int choice;
InitList_L(L);
while (1)
{
menu();
printf("请输入菜单序号:\n");
scanf("%d", &choice);
if (0 == choice) break;
switch (choice)
{
case 1:Create_R(L); break;//这里调用尾插法进行创建
case 2:ListPrint_L(L); break;
case 3:Insert(L); break;
case 4:Delete(L); break;
case 5:Search1(L); break;
case 6:Search2(L); break;
case 7:GetLength(L); break;
case 8:Empty(L); break;
case 9:IsEmpty(L); break;
default:printf("输入错误!!!\n");
}
}
return 0;
}