版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons)
C 双向循环链表:创建、插入、遍历、求长、查找、删除、排序、销毁
一、双向循环链表存在的意义
数组这样的结构提供了连续内存的访问和使用,链表是对内存零碎空间的有效组织和使用,双向循环链表增大了访问的自由度。
二、节点的定义
typedef struct node
{
int data;
struct node *pre;
struct node *next;
}Node;
三、实现
单向链表掌握了,双向循环链表学起来就很容易了。
1.创建(即创建一个空链表)
Node * createList()
{
Node * head = (Node *)malloc(sizeof(Node));
if (NULL == head)
exit(-1);
head->pre = head;
head->next = head;
return head;
}
2.插入(头插法)
void insertList(Node* head,int input)
{
Node * ptr = (Node *)malloc(sizeof(Node));
if (NULL == ptr)
exit(-1);
ptr->data = input;
ptr->next = head->next;
ptr->pre = head;
head->next = ptr;
ptr->next->pre = ptr;
}
3.遍历
正向和反向都可以
void traverseNList(Node* head)
{
Node* tmp = head->next;
while (tmp != head)
{
printf("%-3d", tmp->data);
tmp = tmp->next;
}
}
void traversePList(Node* head)
{
Node* tmp = head->pre;
while (tmp != head)
{
printf("%-3d", tmp->data);
tmp = tmp->pre;
}
}
4.求长
int lengthList(Node* head)
{
int len = 0;
Node* tmp = head->next;
while (tmp != head)
{
len++;
tmp = tmp->next;
}
return len;
}
5.查找
Node * findDataList(Node* head, int findData)
{
Node* fnext=head->next, *fpre = head->pre;
while (fpre != fnext->pre)
{
if (findData == fnext->data)
return fnext;
if (findData == fpre->data)
return fpre;
if (fnext == fpre)
break;
fnext = fnext->next;
fpre = fpre->pre;
}
return NULL;
}
下面分析找不到结束查找的情况:
①查找的链表节点为偶数个:
②查找的链表节点为奇数个:
6.删除
void deleteDataList(Node *pfind)
{
pfind->pre->next = pfind->next;
pfind->next->pre = pfind->pre;
free(pfind);
}
7.排序
冒泡排序
void sortList(Node *head)
{
int N=lengthList(head);
Node *p,*q;
for (int i = 0; i < N - 1; i++)
{
p = head->next;
q = p->next;
for (int j = 0; j < N - i - 1; j++)
{
if (p->data > q->data)
{
p->pre->next = q;
q->pre = p->pre;
p->next = q->next;
p->pre = q;
q->next = p;
p->next->pre = p;
q = p->next;
continue;
}
p = p->next;
q = q->next;
}
}
}
当需要交换时:
8.销毁
直接head->pre->next=NULL;破坏链表结构,使其变为单向链表。
void destroyList(Node * head)
{
head->pre->next=NULL;
Node *tmp;
while (head)
{
tmp = head;
head = head->next;
free(tmp);
}
}
四、综合
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct node
{
int data;
struct node *pre;
struct node *next;
}Node;
Node * createList();
void insertList(Node* head,int input);
void traverseNList(Node* head);
void traversePList(Node* head);
int lengthList(Node* head);
Node * findDataList(Node* head,int findData);
void deleteDataList(Node *pfind);
void sortList(Node *head);
void destroyList(Node * head);
int main()
{
srand(time(NULL));
Node * head = createList();
for (int i = 0; i < 10; i++)
{
insertList(head,rand()%100);
}
printf("create and insert the list:\n");
traverseNList(head);
//traversePList(head);
int listLen = lengthList(head);
printf("\nlength of the list:%d\n",listLen);
Node *flist = findDataList(head,0);
if (flist)
{
printf("find!delete data 0\n");
deleteDataList(flist);
traverseNList(head);
}
else
printf("find none!\n");
printf("\nsort the list:\n");
sortList(head);
traverseNList(head);
destroyList(head);
return 0;
}
Node * createList()
{
Node * head = (Node *)malloc(sizeof(Node));
if (NULL == head)
exit(-1);
head->pre = head;
head->next = head;
return head;
}
void insertList(Node* head,int input)
{
Node * ptr = (Node *)malloc(sizeof(Node));
if (NULL == ptr)
exit(-1);
ptr->data = input;
ptr->next = head->next;
ptr->pre = head;
head->next = ptr;
ptr->next->pre = ptr;
}
void traverseNList(Node* head)
{
Node* tmp = head->next;
while (tmp != head)
{
printf("%-3d", tmp->data);
tmp = tmp->next;
}
}
void traversePList(Node* head)
{
Node* tmp = head->pre;
while (tmp != head)
{
printf("%-3d", tmp->data);
tmp = tmp->pre;
}
}
int lengthList(Node* head)
{
int len = 0;
Node* tmp = head->next;
while (tmp != head)
{
len++;
tmp = tmp->next;
}
return len;
}
Node * findDataList(Node* head, int findData)
{
Node* fnext=head->next, *fpre = head->pre;
while (fpre != fnext->pre)
{
if (findData == fnext->data)
return fnext;
if (findData == fpre->data)
return fpre;
if (fnext == fpre)
break;
fnext = fnext->next;
fpre = fpre->pre;
}
return NULL;
}
void deleteDataList(Node *pfind)
{
pfind->pre->next = pfind->next;
pfind->next->pre = pfind->pre;
free(pfind);
}
void sortList(Node *head)
{
int N=lengthList(head);
Node *p,*q;
for (int i = 0; i < N - 1; i++)
{
p = head->next;
q = p->next;
for (int j = 0; j < N - i - 1; j++)
{
if (p->data > q->data)
{
p->pre->next = q;
q->pre = p->pre;
p->next = q->next;
p->pre = q;
q->next = p;
p->next->pre = p;
q = p->next;
continue;
}
p = p->next;
q = q->next;
}
}
}
void destroyList(Node * head)
{
head->pre->next=NULL;
Node *tmp;
while (head)
{
tmp = head;
head = head->next;
free(tmp);
}
}