【数据结构-思维导图】第二章:线性表

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
//线性表
//顺序表
#include<iostream>
#define MAX_SIZE 10000
#define OK 1
#define INFEASIBLE -1
#define OVERFLOW -2
#define ERROR 0
typedef int Status;
typedef char ElemType;

typedef struct
{
	ElemType* elem;
	int length;
}SqList;
// 1.初始化
Status InitList_Sq(SqList& L)
{
	L.elem = new ElemType[MAX_SIZE];
	if (!L.elem) exit(OVERFLOW);
	L.length = 0;
	return OK;
}
//2.销毁
void DestroyList(SqList& L)
{
	if (L.elem) delete L.elem;
}
//3.清空
void ClearList(SqList& L)
{
	L.length = 0;
}
//4.求长度
int GetLength(SqList L)
{
	return L.length;
}
//5.判断线性表是否为空
bool IsEmpty(SqList L)
{
	if (L.length == 0)
		return 1;
	return 0;
}
//6.取值
int GetElem(SqList L, int i, ElemType& e)
{
	if (i<1 || i>L.length) return -1;
	e = L.elem[i - 1];//随机存取
	return OK;
}
//7.查找元素

//int LocateElem(SqList L, ElemType e)
//{
//	for (int i = 0;i < L.length;i++)
//	{
//		if (e == L.elem[i])
//			return i + 1;//查找成功,返回序号
//	}
//	return 0;//查找失败,返回0
//}
int LocateElem(SqList L, ElemType e)
{
	int i = 0;
	while (i < L.length && e != L.elem[i]) i++;
	if (i < L.length) return i + 1;
	return 0;
	//平均查找长度ASL(期望值):(n+1)/2
}
//8.插入元素(这里的i是逻辑位序,是从1开始的,这点非常重要!)
Status InsertElem(SqList& L,int i, ElemType e)
{
	//存储空间是否已满
	if (L.length == MAX_SIZE) return ERROR;
	//插入位置是否合法
	if (i<1 || i>L.length+1) return ERROR;
	//从尾部开始往后搬
	for (int j = L.length-1;j >= i-1;j--)
	{
		L.elem[j+1] = L.elem[j];
	}
	L.elem [i-1] = e;
	L.length++;
	return OK;
}
//9.删除元素
Status DeleteList(SqList& L, int i)
{
	//删除位置是否合法(注意和插入不一样)
	if (i<1 || i>L.length ) return ERROR;
	for (int j = i ;j <= L.length-1;j++)
	{
		L.elem[j-1] = L.elem[j];
	}
	L.length--;
	return OK;
}
cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
typedef int ElemType;
typedef int Status;
#define OK 1
#define ERROR -1
using namespace std;
//单链表的存储结构
typedef struct Lnode
{
	ElemType data;
	struct Lnode* next;
}Lnode,*LinkList;

//定义链表L:LinkList L;
//定义结点指针p:Lnode* p;

//1.初始化(带头结点)
Status InitList(LinkList& L)
{
	L = new Lnode;
	L->next = nullptr;
	return OK;
}

//2.判断链表是否为空
int ListEmpty(LinkList L)
{
	if (L->next)
		return 0;
	else
		return 1;
}

//3.销毁单链表(包括头结点)
Status DestroyList_L(LinkList& L)
{
	Lnode* p;
	while (L)
	{
		p = L;
		L = L->next;
		delete p;
	}
	return OK;
}

//4.清空链表(保留头结点)
Status ClearList(LinkList& L)
{
	Lnode* p, * q;
	p = L->next;
	while (p)
	{
		q = p->next;
		delete p;
		p = q;
	}
	L->next = nullptr;
	return OK;
}

//5.求单链表L的表长
int ListLength_L(LinkList L)
{
	Lnode* p;
	int cnt = 0;//计数器
	p = L->next;
	while (p)
	{
		cnt++;
		p = p->next;
	}
	return cnt;
}

//6.获取单链表L中第i个数据元素的内容通过变量e返回
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++;
	}
	//p为空说明i太大,超过了表长
	//j>i说明i不合理,例如0,-1(非常重要!直接跳出上面循环了)
	if (!p || j > i)
		return ERROR;
	e = p->data;
	return OK;
}

//7.按值查找:根据指定数据获取该数据位置序号
int LocateElem_L(LinkList L, ElemType e)
{
	Lnode* p;
	p = L->next;
	int j = 1;
	//能从L->next开始的原因:
	//头结点中不包含数据
	while (p && p->data != e)
	{
		p = p->next;
		j++;
	}
	if (p) return j;
	else return 0;
}

//8.在第i个元素之前插入数据元素e
Status ListInsert_L(LinkList& L, int i, ElemType e)
{
	Lnode* p;
	p = L;
	int j = 0;
	/*p = L->next;
	int j = 1;*/
	//不能这么写的原因(关键!):
	//从 L->next(第一个数据节点)开始 
	// → j=1(但会丢失头结点的定位,无法插入到第一个位置);
	
	//首先找到第i-1个元素
	while (p && j < i-1)
	{
		p = p->next;
		j++;
	}
	if (!p || j > i - 1)
		return ERROR;
	Lnode* s = new Lnode;
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

//9.删除链表中第i个数据元素
Status ListDelete_L(LinkList& L, int i, ElemType& e)
{
	Lnode* p;
	p = L;
	int j = 0;
	//首先找到第i-1个元素
	while (p->next/*注意*/ && j < i - 1)
	{
		p = p->next;
		j++;
	}
	if (!(p->next) || j > i - 1)
		return ERROR;
	Lnode* q;
	q = p->next;//临时保存被删结点的地址以备释放
	p->next = q->next;
	e = q->data;
	delete q;
	return OK;
}

//建立一个带头结点单链表
//1.头插法(逆序输入)
void CreateList_H(LinkList& L, int n)
{
	//先建立一个带头节点的空单链表
	L = new Lnode;
	L->next = nullptr;
	while (n--)
	{
		Lnode* p = new Lnode;
		cin >> p->data;
		p->next = L->next;
		L->next = p;
	}
}

//2.尾插法(正序输入)
void CreateList_R(LinkList& L, int n)
{
	L = new Lnode;
	L->next = nullptr;
	Lnode* r=L;//尾结点
	while (n--)
	{
		Lnode* p=new Lnode;
		cin >> p->data;
		p->next = nullptr;
		r->next = p;
		r = p;
	}
}

//测试函数
void PrintList(LinkList L)
{
	Lnode* p = L->next;
	while (p)
	{
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}

int main()
{
	LinkList L1, L2;
	int n = 3;

	cout << "输入3个数字(头插法,逆序存储):";
	CreateList_H(L1, n);
	cout << "头插法结果:";
	PrintList(L1);  // 例如输入1 2 3,输出3 2 1

	cout << "输入3个数字(尾插法,正序存储):";
	CreateList_R(L2, n);
	cout << "尾插法结果:";
	PrintList(L2);  // 例如输入1 2 3,输出1 2 3

	return 0;
}
相关推荐
礼拜天没时间.2 小时前
力扣热题100实战 | 第25期:K个一组翻转链表——从两两交换到K路翻转的进阶之路
java·算法·leetcode·链表·递归·链表反转·k个一组翻转链表
Swift社区2 小时前
LeetCode 400 第 N 位数字
算法·leetcode·职场和发展
再难也得平2 小时前
力扣239. 滑动窗口最大值(Java解法)
算法·leetcode·职场和发展
摩尔曼斯克的海2 小时前
力扣面试题--双指针类
python·算法·leetcode
灰色小旋风2 小时前
力扣——第7题(C++)
c++·算法·leetcode
Ralph_Y3 小时前
C++网络:一
开发语言·网络·c++
程序猿编码3 小时前
探秘 SSL/TLS 服务密码套件检测:原理、实现与核心设计(C/C++代码实现)
c语言·网络·c++·ssl·密码套件
故事和你913 小时前
sdut-程序设计基础Ⅰ-实验二选择结构(1-8)
大数据·开发语言·数据结构·c++·算法·优化·编译原理
努力学算法的蒟蒻3 小时前
day106(3.7)——leetcode面试经典150
算法·leetcode·面试