/*====双向循环链表基本框架(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;
}