嵌入式C语言入门——循环链表、双链表、循环双链表

循环链表

  • 循环链表最后一个结点node->next重新指向头结点ls->head
  • 在单向链表的基础上将所有NULL的判断改写成是否为头结点

循环链表的创建

  1. 链表没有结点的时候,头结点指向自身
    ls->head->next = ls->head;
List *CreateList()
{
	List *ls = (List*)malloc(sizeof(List)/sizeof(char));
	if (NULL == ls)
		return NULL;
	
	// 创建头结点
	ls->head = (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == ls->head)
	{
		free(ls);
		return NULL;
	}
	
	ls->head->next = ls->head;   // 空链表
	
	return ls;
}

循环链表的头插

BOOL Insert_Head(List *ls, Data data)
{
	if (NULL == ls)
		return ERROR;
	
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;
	node->next = ls->head->next;
	ls->head->next = node;
	
	return TRUE;
}

循环链表的尾插


BOOL Insert_Last(List *ls, Data data)
{
	if (NULL == ls)
		return ERROR;
	
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;
	node->next = ls->head;
	
	Node *tmp = ls->head;         // 头结点
	while (tmp->next != ls->head)
	{
		tmp = tmp->next;
	}
	
	tmp->next = node;
	
	return TRUE;
}

循环链表的任意位置插入

BOOL Insert_Pos(List *ls, int pos, Data data)
{
	if(NULL == ls|| pos<1)
		return ERROR;
	
	Node *tmp = ls->head;
	int i;
	for (i = 0; i<pos-1; i++)
	{
		tmp = tmp->next;
		if (tmp == ls->head)  // 越界
		{
			printf ("长度越界: %d\n", pos);
			return ERROR;
		}
	}
	
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;
	node->next = tmp->next; 		
	tmp->next  = node;
	
				
	return TRUE;
}

循环链表按位置删除

BOOL Delete_Pos(List *ls, int pos)
{
	if(NULL == ls|| pos<1)
		return ERROR;
	
	Node *tmp = ls->head;
	int i;
	for (i = 0; i<pos-1; i++)
	{
		tmp = tmp->next;
		if (tmp == ls->head || tmp->next == ls->head)  // 越界
		{
			printf ("长度越界: %d\n", pos);
			return ERROR;
		}
	}
	
	Node *p = tmp->next;
	tmp->next = p->next;
	free(p);
				
	return TRUE;
}

循环链表的逆序

BOOL Reverse(List *ls)
{
	// NULL ==ls || NULL == ls->head    链表不存在
	// NULL == ls->head->next           空链表
	// NULL == ls->head->next->next     只有一个结点的链表
	if (NULL == ls || NULL == ls->head || ls->head == ls->head->next || ls->head == ls->head->next->next)
		return ERROR;
	
	Node *pre = ls->head->next;    // 第一个结点
	Node *cur = pre->next;         // 第二个结点
	Node *tmp;                     // 保存当前结点的下一个结点
	
	while (cur != ls->head)
	{
		tmp = cur->next;
		cur->next = pre;
		
		pre = cur;
		cur = tmp;
	}
	
	ls->head->next->next = ls->head;	//将原来第一个结点的指针域指向NULL
	ls->head->next = pre;				//将头结点的next指向最后一个元素
	
	return TRUE;
}

循环链表的销毁

void Destroy(List *ls)
{
	if (NULL == ls)
		return;
	
	Node *tmp = ls->head;
	while (tmp->next != ls->head)
	{
		Node *p = tmp->next;
		tmp->next = p->next;
		free(p);
	}
	
	free(ls->head);
	free(ls);
}

双链表

双链表有指针域有两个指针,一个指向下一个结点,一个指向前一个结点

双链表的创建

vList *CreateList()
{
	List *ls = (List*)malloc(sizeof(List)/sizeof(char));
	if (NULL == ls)
		return NULL;
	
	// 创建头结点
	ls->head = (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == ls->head)
	{
		free(ls);
		return NULL;
	}
	
	ls->head->next = NULL;   // 空链表
	ls->head->pre  = NULL;     //包含两个指针
	
	return ls;
}

双链表的头插

BOOL Insert_Head(List *ls, Data data)
{
	if (NULL == ls)
		return ERROR;
	
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;

	node->next = ls->head->next;
	ls->head->next = node;
	node->pre = ls->head;
	if (NULL != node->next)
	node->next->pre = node;
	
	return TRUE;
}

双链表的尾插

BOOL Insert_Last(List *ls, Data data)
{
	if (NULL == ls)
		return ERROR;
	
	
	Node *tmp = ls->head;         // 头结点
	while (tmp->next)
	{
		tmp = tmp->next;
	}
	
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;

	node->next = NULL;
	tmp->next = node;
	node->pre = tmp;
	
	return TRUE;
}

双链表按任意位置插

BOOL Insert_Pos(List *ls, int pos, Data data)
{
	if(NULL == ls|| pos<1)
		return ERROR;
	
	Node *tmp = ls->head;
	int i;
	for (i = 0; i<pos-1; i++)
	{
		tmp = tmp->next;
		if (tmp == NULL)  // 越界
		{
			printf ("长度越界: %d\n", pos);
			return ERROR;
		}
	}
	
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;


	node->next = tmp->next; 		
	tmp->next  = node;
	if (node->next != NULL)
		node->next->pre = node;
	
				
	return TRUE;
}

双链表按位置删除

BOOL Delete_Pos(List *ls, int pos)
{
	if(NULL == ls|| pos<1)
		return ERROR;
	
	Node *tmp = ls->head;
	int i;
	for (i = 0; i<pos-1; i++)
	{
		tmp = tmp->next;
		if (tmp == NULL || tmp->next == NULL)  // 越界
		{
			printf ("长度越界: %d\n", pos);
			return ERROR;
		}
	}
	
	Node *p = tmp->next;
	tmp->next = p->next;

	if (NULL != p->next)
		p->next->pre = tmp;
	free(p);
				
	return TRUE;
}

双链表的逆序

BOOL Reverse(List *ls)
{
	// NULL ==ls || NULL == ls->head    链表不存在
	// NULL == ls->head->next           空链表
	// NULL == ls->head->next->next     只有一个结点的链表
	if (NULL == ls || NULL == ls->head || NULL == ls->head->next || NULL == ls->head->next->next)
		return ERROR;
	
/*	Node *pre = ls->head->next;    // 第一个结点
	Node *cur = pre->next;         // 第二个结点
	Node *tmp;                     // 保存当前结点的下一个结点
	
	while (cur)
	{
		tmp = cur->next;
		cur->next = pre;
		
		pre = cur;
		cur = tmp;
	}
	
	ls->head->next->next = NULL;	//将原来第一个结点的指针域指向NULL
	ls->head->next = pre;			//将头结点的next指向最后一个元素*/

	Node *cur = ls->head->next;
	while(cur->next)//最后结点不交换
	{
		Node *tmp = cur->next;	//保存cur的next指针
		cur->next = cur->pre;	//next和pre交换
		cur->pre = tmp;			
		cur = tmp;				//移动

	}
	
	ls->head->next->next = NULL;//第一个元素nextNULL
	ls->head->next = cur;
	cur->next = cur->pre;	//手动交换
	cur->pre = ls->head;

	return TRUE;
}

双链表的销毁

void Destroy(List *ls)
{
	if (NULL == ls)
		return;
	
	Node *tmp = ls->head;
	while (tmp->next)
	{
		Node *p = tmp->next;
		tmp->next = p->next;
		free(p);
	}
	
	free(ls->head);
	free(ls);
}

双向循环链表

双向循环链表在双链表的基础上,将最后一个结点的尾指针重新指向头结点

双向循环链表的创建

List *ls = (List*)malloc(sizeof(List)/sizeof(char));
	if (NULL == ls)
		return NULL;
	
	// 创建头结点
	ls->head = (Node*)malloc(sizeof(Node)/sizeof(char));
	if(NULL == ls->head)
	{
		free(ls);
		return NULL;
	}
	
	ls->head->next = ls->head;   // 空链表
	ls->head->pre  = ls->head;
	
	return ls;

双向循环链表的头插

	if (NULL == ls)
		return ERROR;
	
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;

	node->next = ls->head->next;
	ls->head->next = node;
	node->pre = ls->head;
	node->next->pre = node;
	
	return TRUE;

双向循环链表的尾插

BOOL Insert_Last(List *ls, Data data)
{
	if (NULL == ls)
		return ERROR;
	
	
	Node *tmp = ls->head;         // 头结点
	while (tmp->next != ls->head)
	{
		tmp = tmp->next;
	}
	
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;

	node->next = ls->head;
	tmp->next = node;
	node->pre = tmp;
	ls->head->pre = node;
	
	return TRUE;
}

双向循环链表的按任意位置插

BOOL Insert_Pos(List *ls, int pos, Data data)
{
	if(NULL == ls|| pos<1)
		return ERROR;
	
	Node *tmp = ls->head;
	int i;
	for (i = 0; i<pos-1; i++)
	{
		tmp = tmp->next;
		if (tmp == ls->head)  // 越界
		{
			printf ("长度越界: %d\n", pos);
			return ERROR;
		}
	}
	
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;


	node->next = tmp->next; 		
	tmp->next  = node;
	node->next->pre = node;
	
				
	return TRUE;
}

双向循环链表的按任意位置删除

BOOL Delete_Pos(List *ls, int pos)
{
	if(NULL == ls|| pos<1)
		return ERROR;
	
	Node *tmp = ls->head;
	int i;
	for (i = 0; i<pos-1; i++)
	{
		tmp = tmp->next;
		if (tmp == NULL || tmp->next == NULL)  // 越界
		{
			printf ("长度越界: %d\n", pos);
			return ERROR;
		}
	}
	
	Node *p = tmp->next;
	tmp->next = p->next;

	if (NULL != p->next)
		p->next->pre = tmp;
	free(p);
				
	return TRUE;
}

双向循环链表的逆序

BOOL Reverse(List *ls)
{
	// NULL ==ls || NULL == ls->head    链表不存在
	// NULL == ls->head->next           空链表
	// NULL == ls->head->next->next     只有一个结点的链表
	if (NULL == ls || NULL == ls->head || NULL == ls->head->next || NULL == ls->head->next->next)
		return ERROR;
	
/*	Node *pre = ls->head->next;    // 第一个结点
	Node *cur = pre->next;         // 第二个结点
	Node *tmp;                     // 保存当前结点的下一个结点
	
	while (cur)
	{
		tmp = cur->next;
		cur->next = pre;
		
		pre = cur;
		cur = tmp;
	}
	
	ls->head->next->next = NULL;	//将原来第一个结点的指针域指向NULL
	ls->head->next = pre;			//将头结点的next指向最后一个元素*/

	Node *cur = ls->head->next;
	while(cur->next != ls->head)
	{
		Node *tmp = cur->next;	//保存cur的next指针
		cur->next = cur->pre;	//next和pre交换
		cur->pre = tmp;			
		cur = tmp;				//移动

	}
	
	cur->next = cur->pre;
	cur->pre = ls->head;
	ls->head->pre = ls->head->next;	//逆序
	ls->head->next = cur;

	return TRUE;
}

双向循环链表的销毁

void Destroy(List *ls)
{
	if (NULL == ls)
		return;
	
	Node *tmp = ls->head;
	while (tmp->next != ls->head)
	{
		Node *p = tmp->next;
		tmp->next = p->next;
		free(p);
	}
	
	free(ls->head);
	free(ls);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值