<数据结构与算法>双向循环链表的全面基本框架(C语言描述)

/*====双向循环链表基本框架(C语言描述)=====*/
/*
*作者:wsg
*时间:2017年8月29日
*/

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

/*1.节点的设计
*包含:
*1).数据域。
*2).前趋指针。
*3).后趋指针。
*/
typedef int datatype;
typedef struct node
{
	datatype data; /* 数据域 */
	
	struct node *prev; /* 前趋指针 */
	struct node *next; /* 后趋指针 */
}dbl_clc_lnk_list, *dcl_list;

/* 2.链表的初始化 */
dcl_list init_list(void)
{
	dcl_list mylist = (struct node*)malloc(sizeof(dbl_clc_lnk_list));
	if (mylist != NULL)
	{
		mylist->prev = mylist;
		mylist->next = mylist;
	}
	return mylist;
}

/* 3.判断链表是否为空 */
bool is_empty(dcl_list mylist)
{
	return mylist->prev == mylist->next;
}

/* 4.创建节点 */
dcl_list create_node(datatype data)
{
	dcl_list new_node = malloc(sizeof(dbl_clc_lnk_list));
	if (new_node != NULL)
	{
		new_node->data = data;
		new_node->prev = new_node->next = NULL;
	} 
	return new_node;
}

/* 5.插入节点*/
/* 第一种情况:将新节点插入到目标节点someone之前 */
void insert_prev(dcl_list someone, dcl_list new)
{
	if (someone == NULL || new == NULL)
	{
		return;
	}
	
	/* ①将new的前趋指针指向target前一个节点 */
	new->prev = someone->prev;
	
	/* ②将new的后趋指针指向target */
	new->next = someone;
	
	/* ③将target的前一个节点的后趋指针指向new */
	someone->prev->next = new;
	
	/* ④将target的前趋指针指向new */
	someone->prev = new;
}

/* 第二种情况:将新节点插入到节点someone之后 */
void insert_next(dcl_list someone, dcl_list new)
{
	if (someone == NULL || new == NULL)
	{
		return;
	}
	
	/* ①将new的前趋指针指向target*/
	new->prev = someone;
	
	/* ②将new的后趋指针指向sonmeon的下一个节点 */
	new->next = someone->next;
	
	/* ③将someone的前一个节点的后趋指针指向new */
	someone->next->prev = new;
	
	/* ④将someone的前趋指针指向new */
	someone->next = new;
}

//6.删除节点
void remove_node(dcl_list delete)
{
	if (delete == NULL)
		return;
	/*①将delete节点的前一个节点的后趋指针指向delete节点的下一个节点 */
	delete->prev->next = delete->next;
	/*②将delete节点的下一个节点的前趋指针指向delete节点的下一个节点 */
	delete->next->prev = delete->prev;
	
	/* ③将delete节点的前、后趋指针都指向NULL */
	delete->prev = delete->next = NULL;	
}

/* 7.移动节点 */
/* 第一种情况:将目标节点target移动到节点someone之前 */
void move_prev(dcl_list someone, dcl_list target)
{
	/* 先删除,再插入 */
	remove_node (target);
	insert_prev (someone, target);
	
}

/* 第二种情况:将目标节点移动到目标节点之后 */
void move_next(dcl_list someone, dcl_list target)
{
	/* 先删除,再插入 */
	remove_node(target);
	insert_next(someone, target);
}

/* 8.查找节点 */
dcl_list find_node(dcl_list mylist, datatype data)
{
	if (is_empty(mylist))
		return NULL;
	
	dcl_list tmp = mylist->next;
	while(tmp != mylist)
	{
		if (tmp->data == data)
		{
			return tmp;
		}
		tmp = tmp->next;
	}
	return mylist;
}

/* 9.修改节点数据 */
void modify_node(dcl_list change)
{
	if (change == NULL)
		return; 
	
	datatype tmp;
	printf("将%d修改为(请输入):", change->data);
	scanf("%d", &tmp);
	
	change->data = tmp;	
}

/* 10.遍历链表 */
void display_list(dcl_list mylist)
{
	if (is_empty(mylist))
		return;
	
	dcl_list tmp = mylist;
	while(tmp->next != mylist)
	{
		tmp = tmp->next;
		printf("%d\t", tmp->data);
	}
	printf("\n");
}

/* 11.清空链表 */
void clear_list(dcl_list mylist)
{
	/* 思路:从头节点开始,挨个删除 */
	
	if (is_empty(mylist))
		return;
	
	dcl_list tmp = mylist;
	while(tmp->next != mylist)
	{
		remove_node(tmp->next);
	}
}

int main(int argc, char *argv[])
{
	//1.初始化链表
	dcl_list mylist = init_list();
	
	//2.创建新节点并插入(插到链表末尾,头结点之前)
	printf("(6-5-4)依次插入到链表末尾:\n");
	
	dcl_list new;
	new = create_node(6);
	insert_prev(mylist, new);
	
	new = create_node(5);
	insert_prev(mylist, new);
	
	new = create_node(4);
	insert_prev(mylist, new);
	//3.遍历显示
	display_list(mylist); 
	
	//3.创建新节点并插入节点(插到链表头,头结点之后)
	printf("(3-2-1)依次插入到链表头:\n");
	new = create_node(3);
	insert_next(mylist, new);
	
	new = create_node(2);
	insert_next(mylist, new);
	
	new = create_node(1);
	insert_next(mylist, new);
	//遍历显示
	display_list(mylist);
	
	//4.删除节点
	printf("将3删除掉!\n");
	dcl_list delete = find_node(mylist, 3);
	remove_node(delete);
	//遍历显示
	display_list(mylist); 
	
	//5.移动节点
	/* 1)将3移动到头节点之后 */
	printf("将6移动到链表首!\n");
	dcl_list f_node = find_node(mylist, 6);
	move_next(mylist, f_node);
	display_list(mylist);
	
	/* 2)将3移动到头结点之前(链表末尾) */
	printf("将6移动到链表末尾!\n");
	f_node = find_node(mylist, 6);
	move_prev(mylist, f_node);
	display_list(mylist);
	
	//6.修改链表数据
	printf("修改5!!!\n");
	dcl_list change = find_node(mylist, 5);
	modify_node(change);
	display_list(mylist);

	//清空链表
	clear_list(mylist);
	printf("清空链表后:\n");
	//遍历显示
	display_list(mylist);

	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值