day 21 双向链表以及循环链表

一、头删

每次删除的都是首节点

s1:phead->next = p->next

if(p->next != NULL)

{s2:p->next->prev=phead}

s3.free(p)

cs 复制代码
int doublist_delete_head(node_t *phead)
{
	if(phead == NULL || is_empty(phead) == 1)
	{
		return -1;
	}
	node_t *p = phead->next;
	phead->next = p->next;
	if(p->next != NULL)
	{
		p->next->prev = phead;
	}
	free(p);
	return 1;
}

二、尾删

步骤:1.找到尾节点

2.p->prev->next = NULL;

3.free(p) ;

cs 复制代码
int doublist_delete_tail(node_t *phead)
{
	if(phead == NULL || is_empty(phead) == 1)
	{
		return -1;
	}
	node_t *p = phead->next;
	while(p->next != NULL)
	{
		p = p->next;
	}
	p->prev->next = NULL;
	free(p);
	return 1;
}

三、删除特定的值

步骤:1.找到要删除的结点

  1. p->prev->nextt=p->next;

3.if (p->next != NUL1)p->next->prev=p->prev;

4.free(p);

四、销毁链表

cs 复制代码
int doublist_destroy(node_t **phead)
{
	if(phead == NULL || *phead == NULL)
	{
		return -1;
	}
	node_t *p = (*phead)->next;
	while(p != NULL)
	{
		node_t *p_temp = p;
		p = p->next;
		free(p_temp);
	}
	free(*phead);
	*phead = NULL;
	return 1;
}

五、循环链表

①创建循环链表

cs 复制代码
node_t * circlelist_creat(void)
{
	node_t *phead = malloc((sizeof(node_t)));
	if(phead == NULL)
	{
		printf("%smalloc fail\n",__func__);
		return NULL;
	}
	phead->next = phead;
	return phead;
}

②插入数据(头插)

头插:

sl.创建新节点,填充数据

s2.链接

a. p_new-next =phead->next;

//找到头节点的上一个结点

//p->next == phead->next

b. p->next =p_new;

//单个结点时数据结点指向自己

if(p_new->next == phead)

{

p_new->next = p_new;

}

cs 复制代码
void circlelist_insert_head(node_t *phead,date_t date)
{
	if(phead == NULL)
	{
		return ;
	}
	node_t *p_new = malloc(sizeof(node_t));
	p_new->date = date;
	p_new->next = phead->next;
	node_t *p = phead->next;
	do
	{
		p = p->next;
	}while(p->next != phead->next);
	p->next = p_new;
	if(p_new->next == phead)
	{
		p_new->next = p_new;
	}
}
void circlelist_print(node_t *phead)
{
	if(phead == NULL)
	{
		return ;
	}
	node_t *p = phead->next;
	do
	{
		printf("%d ",p->date);
		p = p->next;
	}while(p != phead->next);
	putchar('\n');
}

③删除

1.node_t *p_temp = p;

//p找到头节点的前一个结点

2.phead->next = p_temp->next;

p->next = p_temp->next;

3.free(p_temp);

cs 复制代码
void circlelist_delete(node_t *phead)
{
	if(phead == NULL || is_empty(phead) == 1)
	{
		return ;
	}
	node_t *p = phead->next;
    node_t *p_temp = p;
	while(p->next != phead->next)
	{
		p = p->next;
	}
	
	phead->next = p_temp->next;
    p->next = p_temp->next;
	free(p_temp);
}

④销毁

销毁的逻辑:

1.p=phead->next->next;

2.循环过程中逐个删除p ==phead->next

3.free(p)4.free(*phead);

*phead= NULL;

cs 复制代码
void circlelist_destory(node_t **phead)
{
	if(phead == NULL || *phead == NULL)
	{
		return ;
	}
	if(is_empty(*phead) == 1)
	{
		free(*phead);
		*phead = NULL;
		return;
	}
	node_t *p = (*phead)->next->next;
	while(p != (*phead)->next)
	{
		node_t *p_temp = p;
		p = p->next;
		free(p_temp);
	}
	free(p);
	free(*phead);
	*phead = NULL;
}

六、栈和队列

1.线性的数据结构

2.特殊受到限制的线性数据结构

3.栈顶操作数据的一端;栈底不能进行数据操作。

顺序栈---以顺序存储结构来实现的栈(数组)为例

算法入栈(压栈)出栈(弹栈)

//1.创建栈 //2.入栈 //3.出栈 //4.获取栈顶元素 //5.获取栈的容量(栈能存放的最大元素个数) //6-栈的大小//此时栈中有效数据的个数 //7.销毁
实现顺序栈:

用数组(顺序表)来实现

栈顶----顺序栈中 top= -1//表示空的栈

栈满----top 来到max-1//栈是满的
入栈:1.移动栈顶2.数据放到栈顶所在位置

int push(seqstack_t *pstack,data_t data)

{

//栈满了is_full

}
出栈:1.先读取栈顶元素2.栈顶往下减空出一个位置

intpop(seqstack_t*pstack,data_t *data

{

//栈空is_empty

]

相关推荐
琢磨先生David2 天前
Day1:基础入门·两数之和(LeetCode 1)
数据结构·算法·leetcode
qq_454245032 天前
基于组件与行为的树状节点系统
数据结构·c#
超级大福宝2 天前
N皇后问题:经典回溯算法的一些分析
数据结构·c++·算法·leetcode
岛雨QA2 天前
常用十种算法「Java数据结构与算法学习笔记13」
数据结构·算法
weiabc2 天前
printf(“%lf“, ys) 和 cout << ys 输出的浮点数格式存在细微差异
数据结构·c++·算法
wefg12 天前
【算法】单调栈和单调队列
数据结构·算法
岛雨QA2 天前
图「Java数据结构与算法学习笔记12」
数据结构·算法
czxyvX2 天前
020-C++之unordered容器
数据结构·c++
岛雨QA2 天前
多路查找树「Java数据结构与算法学习笔记11」
数据结构·算法
AKA__Zas2 天前
初识基本排序
java·数据结构·学习方法·排序