本文介绍两种方式,供理解和学习双链表
方式一
//define
typedef struct Node
{
int data;
struct Node* next;
struct Node* prior;
}Node;
typedef struct DoubleList
{
int length;
Node header;
}DoubleList;
//init
void InitList(DoubleList* L)
{
L->header.next = NULL;
L->length = 0;
}
//create
void CreateList(DoubleList* L, int n)
{
if(n <= 0)
printf("输入的链表长度非法!");
int i = 0;
for(i = 0; i < n; i++)
{
printf("请输入链表位置%d处的值:\n", i);
int num = 0;
scanf("%d", &num);
ListInsert(L, i, num);
}
}
//add
void ListInsert(DoubleList* L, int pos, int e)
{
if(pos < 0 || pos > L->length)
{
printf("插入位置非法!");
return;
}
Node* pCur = &L->header;
int i = 0;
for(i = 0; i < pos; i++)
{
pCur = pCur->next;
}
Node* pNew = (Node*)malloc(sizeof(Node));
if(pos == L->length)
{
pNew->data = e;
pNew->prior = pCur;
pCur->next = pNew;
pNew->next = NULL;
L->length++;
return;
}
pNew->data = e;
pNew->next = pCur->next;
pCur->next->prior = pNew;
pCur->next = pNew;
pNew->prior = pCur;
L->length++;
}
//delete
void ListDelete(DoubleList* L, int pos, int* e)
{
if(pos < 0 || pos >= L->length)
{
printf("删除位置非法,无法删除!");
return;
}
if(L->length == 0)
{
printf("链表为空,无法删除!");
return;
}
Node* pCur = &L->header;
int i = 0;
for(i = 0; i < pos; i++)
{
pCur = pCur->next;
}
Node* pDel = (Node*)malloc(sizeof(Node));
if(pos == L->length-1)
{
pDel = pCur->next;
pCur->next = NULL;
free(pDel);
L->length--;
return;
}
pDel = pCur->next;
*e = pDel->data;
pCur->next = pDel->next;
pDel->next->prior = pCur;
free(pDel);
L->length--;
}
//check
void GetElem(DoubleList* L, int pos, int* e)
{
if(pos < 0 || pos >= L->length)
{
printf("查询位置非法!");
return;
}
if(L->length == 0)
{
printf("链表为空!");
}
Node* pCur = &L->header;
int i = 0;
for(i = 0; i < pos + 1; i++)
{
pCur = pCur->next;
}
*e = pCur->data;
}
打印
void PrintList(DoubleList* L)
{
if(L->length == 0)
{
printf("链表为空,无法打印!");
return;
}
Node* pCur = &L->header;
int i = 0;
for(i = 0; i < L->length; i++)
{
pCur = pCur->next;
printf("链表中位置%d的值为:%d\n", i, pCur->data);
}
}
void PrintList_Reverse(DoubleList* L)
{
if(L->length == 0)
{
printf("链表为空,无法打印!");
return;
}
Node* pCur = &L->header;
int i = 0;
for(i = 0; i < L->length; i++)
{
pCur = pCur->next; //指向最后一个结点
}
for(i = L->length - 1; i >= 0; i--)
{
printf("链表中位置为%d的值为:%d\n", i, pCur->data);
pCur = pCur->prior;
}
}
判空和判长
int ListEmpty(DoubleList* L)
{
if(L->length == 0)
return 1;
else
return 0;
}
int ListLength(DoubleList* L)
{
return L->length;
}
清除和销毁
void ClearList(DoubleList* L)
{
while(L->length)
{
int tmp;
ListDelete(L, 0, &tmp);
}
}
void DestroyList(DoubleList* L)
{
ClearList(L);
free(L);
}
主main
#include <stdio.h>
#include <stdlib.h>
#include "doublelist.h"
int main()
{
DoubleList ls;
InitList(&ls);
printf("The length is %d\n", ls.length);
printf("请输入链表的长度:\n");
int len = 0;
scanf("%d", &len);
CreateList(&ls, len);
PrintList(&ls);
PrintList_Reverse(&ls);
int tmp;
ListDelete(&ls, ls.length-1, &tmp);
PrintList(&ls);
ListDelete(&ls, 0, &tmp);
PrintList(&ls);
ListInsert(&ls, ls.length, 5);
PrintList(&ls);
ListInsert(&ls, 0, 1);
PrintList(&ls);
GetElem(&ls, 0, &tmp);
printf("tmp = %d\n", tmp);
GetElem(&ls, ls.length-1, &tmp);
printf("tmp = %d\n", tmp);
ClearList(&ls);
printf("链表当前长度为:%d\n", ls.length);
DestroyList(&ls);
return 0;
}
方式二
#include <stdlib.h>
#include <stdio.h>
//define
typedef struct duolist
{
struct duolist *front;
int data;
struct duolist *next;
}duolist_t;
//create
duolist_t * create_duolist()
{
duolist_t *list = malloc(sizeof(duolist_t));
list->front = NULL;
list->next = malloc(sizeof(duolist_t));
list->next->front = list;
list->next->next = NULL;
return list;
}
//is null
int isnull(duolist_t *list)
{
return list->next->next == NULL;
}
//add
int insert_head_duolist(duolist_t *list,int data)
{
if(list == NULL)
return -1;
printf("list = %p,%p\n",list,&list);
duolist_t * newnode = malloc(sizeof(duolist_t));
newnode->data = data;
newnode->next = list->next;
newnode->front = list;
newnode->front->next = newnode;
newnode->next->front = newnode;
//list->next->front = newnode;//error code ,because this list is copy,&list is new
//list->next = newnode;
return 0;
}
//delete
int delete_head_duolist(duolist_t *list)
{
if(isnull(list) || list->next->next == NULL)
return -1;
duolist_t *temp = list->next;
temp->next->front = temp->front;
temp->front->next = temp->next;
free(temp);
}
//check
duolist_t *locate_duolist(duolist_t *list,int data)
{
if(isnull(list) || list->next->next == NULL)
return NULL;
while(list->next->next != NULL)
{
if(list->next->data == data)
{
return list;
}
list = list->next;
}
return NULL;
}
//print
int print_duolist(duolist_t* list)
{
if(isnull(list)||list==NULL)
return -1;
while(list->next->next!=NULL)
{
printf("%2d ",list->next->data);
list=list->next;
}
printf("\n");
return 0;
}
//逆打印
int re_print_duolist(duolist_t* list)
{
if(isnull(list)||list==NULL)
return -1;
while(list->next->next!=NULL)
{
list=list->next;
}
list=list->next;
while(list->front->front!=NULL)
{
printf("%2d ",list->front->data);
list=list->front;
}
printf("\n");
return 0;
}
//length
int length_duolist(duolist_t* list)
{
if(isnull(list)||list==NULL)
return 0;
int i=0;
while(list->next->next!=NULL)
{
i++;
list=list->next;
}
return i;
}
//清空
int clear_duolist(duolist_t* list)
{
if(list==NULL||isnull(list))
return -1;
while(length_duolist(list))
{
delete_head_duolist(list);
}
return 0;
}
//销毁
int destroy_duolist(duolist_t* list)
{
if(list==NULL)
return -1;
if(!isnull(list))
clear_duolist(list);
free(list->next);
free(list);
return 0;
}
int main(void)
{
int i;
duolist_t *list = create_duolist();
printf("list = %p,%p\n",list,&list);
for(i = 1;i<=15;i++)
{
insert_head_duolist(list,i);
}
print_duolist(list);
for(i = 1;i<=10;i++)
{
delete_head_duolist(list);
}
print_duolist(list);
insert_head_duolist(locate_duolist(list,4),1515);
print_duolist(list);
re_print_duolist(list);
printf("length_duolist:%d\n",length_duolist(list));
clear_duolist(list);
printf("length_duolist:%d\n",length_duolist(list));
destroy_duolist(list);
}
ubuntu@ubuntu:$ ./a.out
list = 0x1a2e010,0x7ffceebc3198
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
list = 0x1a2e010,0x7ffceebc3168
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
5 4 3 2 1
list = 0x1a2e0d0,0x7ffceebc3168
5 1515 4 3 2 1
1 2 3 4 1515 5
length_duolist:6
length_duolist:0