C语言实现双向链表
双向链表主要实现以下功能:
- 双向链表创建
- 节点头插
- 节点尾插
- 指定位置插入节点
- 节点删除
- 链表排序
- 链表求长
/******************************************************************************************************
* function:自定义一个双向链表,并完成一些双向链表的操作:创建链表、数据插入、数据删除、链表排序
* author:yahai.zhang
* time: 2018.7.15
* File Name:DList.c
******************************************************************************************************/
#include <stdio.h>
/* 定义数据结构 */
struct DouLinkNode {
int data ; //链表中存放的数据,可以自定义数据结构
struct DouLinkNode *pre ,*next;
};
/* 双向链表创建 */
struct DouLinkNode *create(int n)
{
int x;
struct DouLinkNode *head = (struct DouLinkNode *)malloc(sizeof(struct DouLinkNode));
struct DouLinkNode *p,*s;
p = head;
p->pre = NULL;
while(n) {
s = (struct DouLinkNode*)malloc(sizeof(struct DouLinkNode));
printf("input x:");
scanf("%d",&x);
s->data = x;
p->next = s;
s->pre = p;
p = s;
n--;
}
s->next = NULL;
return head;
}
/* 双向链表打印 */
void display(struct DouLinkNode *head)
{
struct DouLinkNode *p = head->next;
while(p->next) {
printf("%d <---> ",p->data);
p = p->next;
}
printf("%d \n ",p->data);
}
/* 链表头插节点 */
void insertListHead(struct DouLinkNode *pList, int data)
{
struct DouLinkNode *pNode = (struct DouLinkNode *)malloc(sizeof(struct DouLinkNode));
pNode->data = data;
pNode->next = pList->next;
pNode->pre = pList;
if (NULL != pNode->next) {
pNode->next->pre = pNode;
}
pList->next = pNode;
}
/* 链表尾插节点 */
void insertListTail(struct DouLinkNode *pList, int data)
{
struct DouLinkNode *pNode = (struct DouLinkNode *)malloc(sizeof(struct DouLinkNode));
pNode->data = data;
struct DouLinkNode *pCur = pList;
while(NULL != pCur->next) {
pCur = pCur->next;
}
pCur->next = pNode;
pNode->pre = pCur;
pNode->next = NULL;
}
/* 在链表的指定位置插入节点: index = 0 ---> 头插; index = length ---> 尾插 */
int insertList(struct DouLinkNode *pList, int data, int index)
{
struct DouLinkNode *pCur = pList;
int len = get_List_Length(pCur);
if(index > len) {
return -1;
} else if (index == 0) {
insertListHead(pList, data);
return 0;
} else if(index == len) {
insertListTail(pList, data);
return 0;
}
struct DouLinkNode *pNode = (struct DouLinkNode *)malloc(sizeof(struct DouLinkNode));
pNode->data = data;
pCur = pList;
int i = 0;
while( index--) {
pCur = pCur->next;
}
pNode->next = pCur->next;
pCur->next = pNode;
pNode->pre = pCur;
pNode->next->pre = pNode;
}
/* 删除链表中的指定值 */
int deleteListNode(struct DouLinkNode *pList, int key)
{
struct DouLinkNode *pPre = pList;
struct DouLinkNode *pCur = pList->next;
int count = 0; //记录删除节点个数
while(NULL!=pCur) {
if(pCur->data == key) {
if(NULL != pCur->next) {
pCur->next->pre = pCur->pre;
}
pCur->pre->next = pCur->next;
pPre = pCur;
pCur = pCur->next;
free(pPre);
count ++;
} else {
pPre = pCur;
pCur = pCur->next;
}
}
return count;
}
/* 链表求长 */
int get_List_Length(struct DouLinkNode *head)
{
struct DouLinkNode *p;
int len = 0;
p = head;
for (p; p->next!=NULL; p=p->next) {
len++;
}
return len;
}
/* 双向链表排序 */
struct DouLinkNode *sort(struct DouLinkNode *head)
{
struct DouLinkNode *p,*s,*min;
int tmp;
for(p = head->next ;p->next!=NULL ;p=p->next) {
min = p ;
for(s= p->next ; s!=NULL ;s=s->next) {
if(s->data <min->data)
min = s; //找到每次排序中最小的节点,然后记住这个节点
} if(min != p) { //把这个节点与前面的节点的数据进行交换,把最小的数据放在前面的节点内。
tmp = min->data;
min->data = p->data;
p->data = tmp;
}
}
return head;
}
void main()
{
struct DouLinkNode *head,*head1;
int n;
int data;
printf("input n:");
scanf("%d",&n);
head = create(n);
display(head);
printf("insert node from head: data=");
scanf("%d", &data);
insertListHead(head, data);
display(head);
printf("insert node from tail: data=");
scanf("%d", &data);
insertListTail(head, data);
display(head);
insertList(head, 5555, 4);
display(head);
printf("please input the data you want to delete: data=");
scanf("%d", &data);
int k = deleteListNode(head, data);
printf("success! delete nodes:%d\n ", k);
display(head);
printf("the list length:%d\n", get_List_Length(head));
head1 = sort(head);
display(head1);
}
运行结果如下所示: