一、雙向循環鏈表
二、用C語言實現雙向循環鏈表
1、構造存儲結構
typedef int datatype;
typedef struct doublelist{
datatype data;
struct doublelist *next, *prev;
}double_list, *double_plist;
2、初始化
初始化主要工作:①申請頭結點內存空間;②
head->next = head; head->prev = head;
3、插入結點
(1)、向p指向的結點後面插入new指向的結點
步驟①:
new->next = p->next;
步驟②:p->next->prev = new;
步驟③:new->prev =p;
步驟④:p->next = new;
/* 向p指向的結點後面插入new指向的結點 */
void insert_doublelist_behind(double_plist p, double_plist new)
{
new->next = p->next;
p->next->prev = new;
new->prev = p;
p->next = new;
}
(2)、向p指向的結點前面插入new指向的結點
步驟①:
new->prev = p->prev;
步驟②:p->prev->next = new;
步驟③:new->next = p;
步驟④:p->prev = new;
/* 向p指向的結點前面插入new指向的結點 */
void insert_doublelist_tail(double_plist p, double_plist new)
{
new->prev = p->prev;
p->prev->next = new;
new->next = p;
p->prev = new;
}
4、刪除結點
(1)、刪除p指向的結點後面的結點
t = p->next;
p->next = t->next;
t->next->prev = p;
free(t);
/* 刪除p指向的結點後面的結點 */
void delete_doublelist_post(double_plist p)
{
double_plist t = NULL;
t = p->next;
p->next = t->next;
t->next->prev = p;
free(t);
}
(2)、刪除p指向的結點前面的結點
t = p->prev;
p->prev = t->prev;
t->prev->next = p;
free(t);
/* 刪除p指向的結點前面的結點 */
void delete_doublelist_prev(double_plist p)
{
double_plist t = NULL;
t = p->prev;
p->prev = t->prev;
t->prev->next = p;
free(t);
}
(3)、刪除p指向的結點
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
/* 刪除p指向的結點*/
void delete_doublelist(double_plist p)
{
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
}
5、判斷鏈表是否爲空
判斷
head->next == head
是否成立即可。
/* 判斷鏈表是否爲空 */
bool isempty_doublelist(double_plist head)
{
if (head == head->next)
{
return true;
}
else
{
return false;
}
}
6、打印鏈表
void show_doublelist(double_plist head)
{
double_plist p = NULL;
for (p = head->next; p != head; p = p->next)
{
printf("%d\t", p->data);
}
printf("\n");
}
三、練習題
用雙向循環鏈表實順序遞增存儲若干自然數,比如輸入一個整數10,則建立一個雙向循環鏈表,裏面的每個節點分別存放1,2,3,4,5,6,7,8,9,10,然後通過某些操作,將其重新排列成1,3,5,7,9,10,8,6,4,2,即奇數升序偶數降序,並在屏幕上打印出來。
1、創建鏈表
/* 創建鏈表 */
void create_doublelist(double_plist head)
{
int n = 0;
int i = 0;
double_plist new = NULL;
printf("請輸入要插入的數據個數:");
scanf("%d", &n);
for (i=0; i<n; i++)
{
new = (double_plist)malloc(sizeof(double_list));
if (NULL == new)
{
perror("malloc");
exit(1);
}
printf("輸入要插入的第%d個數據:", i+1);
scanf("%d", &(new->data));
/* 使用前插方法 */
insert_doublelist_tail(head, new);
show_doublelist(head);
}
}
2、排序
/* 排序 */
void sort_doublelist(double_plist head)
{
double_plist p = NULL;
double_plist t = NULL;
p = head->prev; /* p指向最後那個結點,從後往前找 */
while (p != head)
{
if (1 == (p->data % 2)) /* 判斷是否爲奇數 */
{
p = p->prev; /* 如果是奇數,p往前移 */
}
else /* 偶數 */
{
t = p; /* 保存這個結點的數據 */
p = p->prev; /* p繼續往前移 */
delete_doublelist(t); /* 刪除這個結點,但不釋放它,還繼續保存數據 */
insert_doublelist_tail(head, t); /* 將t結點作爲新結點插入到head結點後面 */
show_doublelist(head);
}
}
}
3、main函數
int main(void)
{
double_plist head = NULL;
init_doublelist(&head);
create_doublelist(head);
sort_doublelist(head);
return 0;
}