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

]

相关推荐
mmmmath_35 分钟前
LeetCode.438.找到字符串中所有字母异位词
数据结构·算法·leetcode
码少女24 分钟前
数据结构——堆排序
数据结构
神仙别闹10 小时前
基于 C++ 实现两个有序链表序列的交集
java·c++·链表
淡海水12 小时前
08-03-不可变-ImmutableDictionary-TKey-TValue-与ImmutableHashSet-T-持久化哈希树
数据结构·算法·c#·哈希算法·dictionary·immutable
203号居民14 小时前
LeetCode hot 100 — 25. K 个一组翻转链表
算法·leetcode·链表
Nil20815 小时前
leetcode 78子集
数据结构·算法·leetcode
喜欢吃燃面16 小时前
深入 C++ STL:从 unordered_set与unordered_map到底层哈希表的原理与实现
数据结构·c++·散列表
en.en..16 小时前
Linux fork() 工作原理
数据结构·算法
不会就选b18 小时前
数据结构之树&&二叉树(二)
数据结构·算法
小刘在重生~20 小时前
Java 集合|Collection、List、ArrayList、LinkedList、泛型、Collections 工具类
java·数据结构·list