数据结构
第二章 线性表的链式表现和实现
单链表的基本操作实现
一、基本算法(数据结构——严蔚敏)
添加的简单算法
//若L为空表,则返回1,否则返回0
void ListEmpty(LinkList& L)
{
if (L->next)
cout << "链表不为空" << endl;
else
cout << "链表为空" << endl;
}
//销毁单链表L
Status DestoryList(LinkList& L)
{
LNode* p;
while (L)
{
p = L;
L = L->next;
delete p;
}
return OK;
}
//将L置为空表
Status CleraList(LinkList& L)
{
LNode* p, * q;
p = L->next;
while (p)
{
q = p->next;
delete p;
p = q;
}
L->next = NULL;
return OK;
}
//求链表长度
int ListLength(LinkList L)
{
LinkList p;
p = L->next;
int i = 0;
while (p)
{
i++;
p = p->next;
}
return i;
}
2.6算法:单链表的初始化
Status InitList(LinkList& L)
{
L = new LNode;
L->next = NULL;
return OK;
}
2.7算法:单链表取值
Status GetElem(LinkList L, int i, ElemType& e)
{
LinkList p;
p = L->next;
int j = 1;
while (p && j < 1)
{
p = p->next;
++j;
}
if (!p || j > i)
return ERROR;
e = p->data;
return OK;
}
单链表取值的平均时间复杂度为O(n)。
2.8算法:单链表的按值查找
//链表的按值查找返回地址
LNode* LocateElem(LinkList L, ElemType e)
{
LNode* p;
p = L->next;
while (p && p->data != e)
p = p->next;
return p;
}
//按值查找返回序号
Status LocateElem_L(LinkList L, ElemType e)
{
LinkList p;
int j = 1;
p = L->next;
while (p && p->data != e)
{
p = p->next;
++j;
}
if (p)
return j;
else
return 0;
}
查找的时间复杂度为O(n)。
2.9、2.10算法:单链表的插入和删除
//链表插入,在第i个元素之前插入元素e
Status ListInsert(LinkList& L, int i, ElemType e)
{
LinkList p, s; int j;
p = L; j = 0;
while (p && j < i - 1)
{
p = p->next; ++j;
}
if (!p || j > i + 1) return ERROR;
s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
//单链表的删除
Status LisetDelete(LinkList& L, int i)
{
LinkList p, s; int j;
p = L; j = 0;
while (p && j < i - 1)
{
p = p->next; ++j;
}
if(!p||j>i+1) return ERROR;
p->next =(p->next)->next;//两种方法
//s = p->next;
//p->next =s->next;
//delete s;
return OK;
}
线性链表不需要移动元素,只需修改指针,时间复杂度为O(1)。
2.11建立单链表——头插法
//单链表创建,头插法(输入数据顺序与显示数据顺序相反)
LinkList CreatList()
{
LinkList L, p;
int i, n;
InitList(L);
cout << "构建数据链表:\n";
cout << "链表中数据个数:\n";
cin >> n;
for (i = 0; i < n; i++)
{
p = new LNode;
cout << "请输入数据: " << endl;
cin >> p->data;
p->next = L->next;
L->next = p;
}
cout << endl;
return L;
}
头插法时间复杂度O(n)。
尾插法
//尾插法——元素插在链表尾部
LinkList CreatList_W()
{
LinkList L, p, r;
int i, n;
InitList(L);
cout << "构建数据链表:\n";
cout << "链表中数据个数:\n";
cin >> n;
r = L;
for (i = 0; i < n; i++)
{
p = new LNode;
cout << "请输入数据: ";
cin >> p->data;
p->next = NULL;
r->next = p;
r = p;
}
cout << endl;
return L;
}
尾插法时间复杂度O(n)。
二、详细代码
1.头文件
#pragma once
#include<iostream>
using namespace std;
//函数结果状态代码
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define MAXSIZE 100//顺序表可能达到的最大长度
typedef int Status;//status是函数类型,其值是函数结果状态代码
typedef int ElemType;// ElemType是元素的数据类型,想要整体改变元素的数据类型只需改变ElemType前的数据类型即可
typedef struct LNode//声明结点的类型和指向结点的指针类型
{
ElemType data;//结点的数据域
struct LNode* next;//结点的指针域
} LNode, * LinkList;//LinkList为指向结构体Lnode的指针类型
//LNode指的是一个结点
2.cpp文件
代码如下(示例):
#include"链式存储.h"
#include<iostream>
using namespace std;
/*各结点有两个域组成
数据域:存储元素数值
指针域:存储直接后继结点的存储位置
结点:数据|指针
链表:n个结点有指针链组成一个链表
无头结点,头指针为空时表示空表:^
有头结点,头指针为空时表示空表:□->□^
头指针->头结点->首元结点(头结点不是数据元素)
*/
//定义链表: LinkList L;
//定义结点指针p: LNode *P; 《==》LinkList p;
Status InitList(LinkList& L);//单链表初始化
LinkList CreatList();
void ShowStudent(LinkList L);
void ListEmpty(LinkList& L);//若L为空表,则返回1,否则返回0
Status DestoryList(LinkList& L);//销毁单链表L
Status CleraList(LinkList& L);//将L置为空表
int ListLength(LinkList L);//求链表长度
Status GetElem(LinkList L, int i, ElemType& e); //获取线性表L中某个数据元素内容,通过变量e返回
LNode* LocateElem(LinkList L, ElemType e);//链表的按值查找返回地址
Status LocateElem_L(LinkList L, ElemType e);//按值查找返回序号
Status ListInsert(LinkList& L, int i, ElemType e);//链表插入,在第i个元素之前插入元素e
//单链表初始化
Status InitList(LinkList& L)
{
L = new LNode;
L->next = NULL;
return OK;
}
//若L为空表,则返回1,否则返回0
void ListEmpty(LinkList& L)
{
if (L->next)
cout << "链表不为空" << endl;
else
cout << "链表为空" << endl;
}
//销毁单链表L
Status DestoryList(LinkList& L)
{
LNode* p;
while (L)
{
p = L;
L = L->next;
delete p;
}
return OK;
}
//将L置为空表
Status CleraList(LinkList& L)
{
LNode* p, * q;
p = L->next;
while (p)
{
q = p->next;
delete p;
p = q;
}
L->next = NULL;
return OK;
}
//求链表长度
int ListLength(LinkList L)
{
LinkList p;
p = L->next;
int i = 0;
while (p)
{
i++;
p = p->next;
}
return i;
}
//获取线性表L中某个数据元素内容,通过变量e返回
Status GetElem(LinkList L, int i, ElemType& e)
{
LinkList p;
p = L->next;
int j = 1;
while (p && j < 1)
{
p = p->next;
++j;
}
if (!p || j > i)
return ERROR;
e = p->data;
return OK;
}
//链表的按值查找返回地址
LNode* LocateElem(LinkList L, ElemType e)
{
LNode* p;
p = L->next;
while (p && p->data != e)
p = p->next;
return p;
}
//按值查找返回序号
Status LocateElem_L(LinkList L, ElemType e)
{
LinkList p;
int j = 1;
p = L->next;
while (p && p->data != e)
{
p = p->next;
++j;
}
if (p)
return j;
else
return 0;
}
//链表插入,在第i个元素之前插入元素e
Status ListInsert(LinkList& L, int i, ElemType e)
{
LinkList p, s; int j;
p = L; j = 0;
while (p && j < i - 1)
{
p = p->next; ++j;
}
if (!p || j > i + 1) return ERROR;
s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
//单链表的删除
Status LisetDelete(LinkList& L, int i)
{
LinkList p, s; int j;
p = L; j = 0;
while (p && j < i - 1)
{
p = p->next; ++j;
}
if(!p||j>i+1) return ERROR;
p->next =(p->next)->next;//两种方法
//s = p->next;
//p->next =s->next;
//delete s;
return OK;
}
//单链表创建,头插法
LinkList CreatList()
{
LinkList L, p;
int i, n;
InitList(L);
cout << "构建数据链表:\n";
cout << "链表中数据个数:\n";
cin >> n;
for (i = 0; i < n; i++)
{
p = new LNode;
cout << "请输入数据: " << endl;
cin >> p->data;
p->next = L->next;
L->next = p;
}
cout << endl;
return L;
}
//显示链表中信息
void ShowStudent(LinkList L)
{
LinkList p;
p = L->next;
while (p)
{
cout << "地址:" << p << " 数据:" << p->data << endl;
p = p->next;
}
}
//主函数
int main()
{
LinkList L;
ElemType e;
int select = 0;
InitList(L);
while (true)
{
cout << "请输入您的选择" << endl;
cout << "0、构建数据链表" << endl;
cout << "1、显示数据信息" << endl;
cout << "2、链表数据判空" << endl;
cout << "3、清空数据链表" << endl;
cout << "4、数据链表表长" << endl;
cout << "5、获取链表元素" << endl;
cout << "6、链表按值查找" << endl;
cout << "7、链表插入数据" << endl;
cout << "8、链表删除数据" << endl;
cout << "99退出系统" << endl;
cin >> select;
switch (select)
{
case 0:
L = CreatList();
system("pause");
system("cls");
break;
case 1:
ShowStudent(L);
system("pause");
system("cls");
break;
case 2:
ListEmpty(L);
system("pause");
system("cls");
break;
case 3:
CleraList(L);
cout << "已将链表清空" << endl;
system("pause");
system("cls");
break;
case 4:
int l;
l = ListLength(L);
cout << "链表表长为" << l << endl;
system("pause");
system("cls");
break;
case 5:
int i;
cout << "输入数据的位置" << endl;
cin >> i;
GetElem(L, i, e);
cout << "该数据为" << e << endl;
system("pause");
system("cls");
break;
case 6:
ElemType a;
int b;
ShowStudent(L);
cout << "输入查找的序号: " << endl;
cin >> a;
b = LocateElem_L(L, a);
cout << "该位置元素为: " << b << endl;
break;
case 7:
ElemType ia;
int idx;
cout << "输入插入的位置: " << endl;
cin >> idx;
cout << "输入插入的数据: " << endl;
cin >> ia;
ListInsert(L, idx, ia);
break;
case 8:
int c;
cout << "输入删除数据的结点:" << endl;
cin >> c;
LisetDelete(L, c);
break;
case 99:
exit(0);
break;
default:
break;
}
}
system("pause");
return 0;
}
总结
仅用来记录个人学习,有什么问题请在评论区指出!