大话数据结构||学习笔记||从开头至链表||c/c++


day 4

1 时间复杂度
在这里插入图片描述
1-1 线性阶
简单
1-2 对数阶
在这里插入图片描述
1-3 平方阶
在这里插入图片描述
常见时间复杂度表
在这里插入图片描述
在这里插入图片描述
2 线性表
2-1 线性表顺序存储结构
在这里插入图片描述
线性表的长度与数组长度区分
在这里插入图片描述
线性表的顺序存储的结构代码


#define MAXSIZE 20     //存储空间初始分配量
typedef int ElemType;  // 暂定int
typedef struct
{
	ElemType date[MAXSIZE];  //数组存储数据成员,最大值为MAXSIZE
	int length;              //线性表当前长度 
}SqList;

在这里插入图片描述
用数组存储,那么存储器中的每个存储单元都是有编号的,这个编号称为地址
在这里插入图片描述
在这里插入图片描述
那么,对于每个线性表位置的存入与取出,对于计算机来说都是相同的时间。它的存储时间性能为O(1)。我们通常把具有这一特点的存储结构称为顺序存储结构。
3 顺序存储结构的插入与删除
3-1 获得元素操作 // wr

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
/* Status 是函数类型,其值是函数结果状态代码,如OK
初始条件:顺序线性表L存在,1<=i<=ListLength(L)
操作结果:用e返回L中第i个数据元素的值*/
Status GetElem(SqList L, int i, ElemType *e)//这个函数为什么我调用不起来
{
	if (L.length == 0 || i<1 || i>L.length)
		return ERROR;
	*e = L.date[i - 1];
	return OK;
}

3-2 插入操作
在这里插入图片描述
折磨个搞法
插入算法的思路

  • 若插入位置不合理,抛出异常
  • 若线性表长度>=数组长度,则抛出异常或动态增加容量
  • 从最后一个位置开始向前遍历,直到i,分别将它们向后移一位
  • 插入元素到i处
  • 表长+1
Status ListInsert(SqList *L, int i, ElemType e)
{
	int k;
	if (L->length == MAXSIZE)//顺序线性表已满
		return ERROR;
	if (i<1 || i>L->length + 1)//当i不在范围内
		return ERROR;
	if (i <= L->length)
	{
		for (k = L->length; k >= i - 1; k--)//将要插入位置后数据元素向后移动一位
			L->date[k + 1] = L->date[k];
	}
	L->date[i - 1] = e;
	L->length++;
	return OK;

}

3-3 删除操作
删除算法的思路

  • 若删除位置不合理,抛出异常
  • 取出删除元素
  • 将删除位置后继元素前移
  • 表长-1
Status ListDelete(SqList *L, int i, ElemType *e)
{
	int k;
	if (L->length == 0)      //表长为0
		return ERROR;
	if (i<1 || i>L->length ) // 删除位置不正确
	{
		return ERROR;
	}
	*e = L->date[i - 1];
	if (i < L->length)//若删除的不是最后一个元素
	{
		for (k = i; k < L->length; k++)//删除位置后继元素前移
			L->date[k - 1] = L->date[k];
	}
	L->length--;
	return OK;
}

3-4 线性表的顺序存储结构的优缺点

在这里插入图片描述
4 线性表的链式存储结构
在这里插入图片描述
在这里插入图片描述
就是这莫简单明了
头结点:
在这里插入图片描述
在这里插入图片描述
注意看头结点和第一个结点,头结点不是第一个结点
4-1 头结点和第一个结点的区别

在这里插入图片描述
4-2 代码描述

typedef struct Node
{
	ElemType date;
	struct Node *next;
}Node;
typedef struct Node *LinkList;//定义 LinkList

在这里插入图片描述
4-3 单链表的读取
算法思路:
算法思路
代码实现:

Status GetElem(LinkList L, int i, ElemType *e)
{
	int j;
	LinkList p; //声明一结点p
	p = L->next;//让p指向链表L的第一个结点
	j = 1;      //j为计数器
	while ( p && j<i)//p不为空,或计数器j还没有到i时,循环继续
	{
		p = p->next;
		++j;
	} 
	if (!p || j > i)  
		return ERROR;//第i个元素不存在
	*e = p->date;    //读取第i个元素
	return OK;
}

4-4 单链表的插入与删除
插入:-------------------------------------
在这里插入图片描述
就是这莫简单
这样就,,,
显然;
单链表第i个元素的插入操作算法思路
思路
代码实现

Status ListInsert(LinkList *L, int i, ElemType e)
{
	int j;
	LinkList p, s;
	p = *L;
	j = 1;
	while (p&&j < i)
	{
		p = p->next;
		++j;
	}
	if (!p || j > i)
		return ERROR;   //第i个元素不存在
	s = (LinkList)malloc(sizeof(Node));//生成新结点(c标准函数)//加个头文件
	s->date = e;
	s->next = p->next;  //基操勿6
	p->next = s;
	return OK;
}

删除:-------------------------------------
h
就这一部到位
单链表第i个数据删除结点的算法思路
在这里插入图片描述
在这里插入图片描述
代码实现

Status ListDelete(LinkList *L, int i, ElemType *e)
{
	int j;
	LinkList p, q;
	p = *L;
	j = 1;
	while (p->next && j < i)
	{
		p = p->next;
		++j;
	}
	if (!(p->next) || j > i)
		return ERROR;  //第i个元素不存在
	q = p->next;
	p->next = q->next; //将q的后继赋值给p的后继
	*e = q->date;      //将q结点中的数据给e
	free(q);           //让系统回收此结点,释放内存
	return OK;
}

4-5 单链表的整表创建 //wr
单链表整表创建的算法思路

  • 声明一结点p和计数器变量i

  • 初始化一空链表L

  • 让L的头结点的指针指向NULL,即建立一个带头结点的单链表

  • 循环

  • 生产一新结点赋值给p

  • 随机生成一数字赋值给p的数据域p->date

  • 将p插入头结点和与前一新结点之间
    代码实现

void CreateListHead(LinkList *L, int n)//头插法
{
	LinkList p;
	int i;
	srand(time(0));                        //初始化随机数种子
	*L = (LinkList)malloc(sizeof(Node)); 
	(*L)->next = NULL;                     //先建立一个带头结点的单链表
	for (i = 0; i < n; i++)
	{
		p = (LinkList)malloc(sizeof(Node));//生成新结点
		p->date = rand() % 100 + 1;        //随机生成100以内的数字
		p->next = (*L)->next;
		(*L)->next = p;                    //插入到表头
	}
}

图示
上面为头插法,下面为尾插法

void CreateListTail(LinkList *L, int n)
{
	LinkList p, r;
	int i;
	srand(time(0));
	*L = (LinkList)malloc(sizeof(Node));//为整个线性表??
	r = *L;                                //r为指向尾部的结点
    for (i = 0; i < n; i++)
	{
			p = (LinkList)malloc(sizeof(Node));//生成新结点
			p->date = rand() % 100 + 1;        //随机生成100以内的数字   
			r->next = p;                       //将表位终端结点的指针指向新结点
			r = p;                             //将当前的新结点定义为表尾终端结点
	}
	r->next = NULL; //表示当前链表结束  /// 解释见图
}

解释:
在这里插入图片描述
6666
4-6 单链表的整表删除
在这里插入图片描述
代码实现

Status ClearList(LinkList *L)
{
	LinkList p, q;
	p = (*L)->next;    //p指向第一个结点
	while (p)          //没到表尾(NULL)
	{
		q = p->next;
		free(p);
		p = q;
	}
	(*L)->next = NULL; //头结点指针域为空
	return OK;
}

简单总结
总结
休息个蛋
5 静态链表
在这里插入图片描述

#define MAXSIZE 1000
typedef struct
{
	ElemType date;
	int cur;      //游标Cursor,为0时表示无指向
}Component,StaticLinkList[MAXSIZE];

在这里插入图片描述

//space[0].cur为头指针,"0"表示空指针
Status InitList(StaticLinkList space)
{
	int i;
	for (i = 0; i < MAXSIZE - 1; i++)
		space[i].cur = i+1;
	space[MAXSIZE - 1] = 0; //目前静态链表为空,最后一个元素的cur为0
	return OK;
}

mengle
5-1 静态链表的插入
在这里插入图片描述

int Malloc_SLL(StaticLinkList space)
{
	int i = space[0].cur;//当前数组第一个元素存的值,就是返回的第一个备用空闲下标
	if (space[0].cur)
		space[0].cur = space[i].cur;//由于要拿出一个分量来使用,所以我们就得
	                                //把他的下一个分量用来做备用
	return i;
}

真的有意思熬
差点没看懂。。。更有意思的在下面
插入:
在这里插入图片描述

Status ListInsert(StaticLinkList L, int i, ElemType e)
{
	int j, k, l;
	k = MAX_SIZE - 1;  //注意k首先是最后一个元素下标 //???哪来的MAX_SIZE
	if (i < 1 || ListLength(L) + 1)
		return ERROR;
	j = Malloc_SLL(L);//获得空闲分量的下标
	if (j)
	{
		L[j].date = e;//将数据赋值给此分量的date
		for (l = 1; l <= i - 1; l++)//找到第i个元素之前的位置
		{
			k = L[k].cur;
		}
		L[j].cur = L[k].cur;//把第i个元素之前的cur赋值给新元素的cur
		L[k].cur = j;       //把新元素的下标赋值给第i个元素之前的元素的cur
		return OK;
	}
}

解释:
在这里插入图片描述
这操作够nb
5-2 静态链表的删除
在这里插入图片描述

//删除在L中的第i个元素e
Status ListDelete(StaticLinkList L, int i)
{
	int j, k;
	if (i<1 || i>ListLength(L))
		return ERROR;
	k = MAX_SIZE - 1;
	for (j = 1; j <= i - 1; j++)
		k = L[k].cur;
	j = L[k].cur;
	L[k].cur = L[j].cur;
	Free_SLL(L, j);
	return OK;
}

在这里插入图片描述

void Free_SLL(StaticLinkList space, int k)
{
	space[k].cur = space[0].cur;//把第一个元素cur值赋给要删除的分量cur
	space[0].cur = k;           //把要删除的分量下标赋值给第一个元素的cur
}

在这里插入图片描述

int ListLength(StaticLinkList L)
{
	int j = 0;
	int i = L[MAX_SIZE - 1].cur;
	while (i)
	{
		i = L[i].cur;
		j++;
	}
	return j;
}

静态链表的优缺点:
在这里插入图片描述
6 循环链表
在这里插入图片描述
....略
在这里插入图片描述
7 双向链表
在这里插入图片描述

typedef struct DulNode
{
	ElemType date;
	struct DulNode *prior;
	struct DulNode *next;
} DulNode,*DuLinkList ;

在这里插入图片描述
在这里插入图片描述
插入:
在这里插入图片描述

s->prior = p;     //把p赋值给s的前驱  1 
s->next = p->next;//把p->next赋值给s的后继  2 
p->next->prior=s; //把s赋值给p->next的前驱  3 
p->next=s;        //把s赋值给p的后继   4 

删除:
在这里插入图片描述
第三章到此结束。根本没搞明白有木有…下一章是栈与队列。
大话数据结构||学习笔记||从开头至链表||c/c++;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值