双向链表的实现【C语言】
概念:
双向链表还是单链表,其逻辑存储是连续的,但物理存储空间不连续
包含数据域、直接前驱域和直接后继域。
可以从前向后遍历,也可以从后向前遍历。
双链表的实现
- 结构的声明:
typedef int elemType;
typedef struct Node
{
union {
int length;
elemType data;
};
struct Node *prior;
struct Node *next;
}doublelist;
- 方法的声明
//方法的声明
void InitDoubleList(doublelist* head);//初始化
bool InsertDoubleList(doublelist* head,int value,int pos);//按位置插入
bool InsertDoubleListHead(doublelist* head,int value);//头插
bool InsertDoubleListRear(doublelist* head,int value);//尾插
bool DeleteDoubleList(doublelist* head,int pos);//按位置删
bool DeleteDoubleListHead(doublelist *head);//头删
bool DeleteDoubleListRear(doublelist *head);//尾删
bool DeleteDoubleListFromVal(doublelist *head,int value);//按值删
bool IsEmpty(doublelist* head);//判空
int GetLength(doublelist* head);//长度
void DestoryDoubleList(doublelist* head);//销毁
- 方法的实现
#include<stdio.h>
#include<stdlib.h>
#include"doublelist.h"
//申请新结点(只在本文件内使用)
static doublelist* ApplyNewNode(doublelist* pri,doublelist* nex,int value)
{
doublelist *new_node = (doublelist *)malloc(sizeof(doublelist));
if (new_node == NULL) return NULL;
new_node->data = value;
new_node->next = nex;
new_node->prior =pri;
return new_node;
}
void InitDoubleList(doublelist* head) //初始化
{
if(head==NULL) exit(0);
head->next =NULL;
head->length =0;
}
bool InsertDoubleList(doublelist* head,int value,int pos) //按位置插入
{
if(head==NULL) exit(0);
if(pos<0 || pos >GetLength(head) ) return false;
doublelist *p=head;
while(pos)
{
p=p->next ;
pos--;
}
doublelist *new_node=ApplyNewNode(p,p->next,value);
if (new_node == NULL) return false;
if(p->next == NULL) //尾插
{
p->next =new_node;
}
else
{
p->next->prior =new_node;
p->next =new_node;
}
head->length ++;
return true;
}
bool InsertDoubleListHead(doublelist* head,int value) //头插
{
if(head==NULL) exit(0);
return InsertDoubleList(head,value,0);
}
bool InsertDoubleListRear(doublelist* head,int value) //尾插
{
if(head==NULL) exit(0);
return InsertDoubleList(head,value,GetLength(head));
}
bool DeleteDoubleList(doublelist* head,int pos) //按位置删
{
if(head == NULL) exit(0);
if (pos < 0 || pos >= GetLength(head)) return false;
doublelist *p = head;
while (pos)
{
p = p->next;
pos--;
}
doublelist *q = p->next;
if(q->next != NULL) //删除尾结点
{
q->next->prior =p;
}
p->next = q->next;
free(q);
head->length--;
return true;
}
bool DeleteDoubleListHead(doublelist *head) //头删
{
if(head==NULL) exit(0);
return DeleteDoubleList(head,0);
}
bool DeleteDoubleListRear(doublelist *head) //尾删
{
if(head== NULL) exit(0);
return DeleteDoubleList(head,GetLength(head) -1);
}
bool DeleteDoubleListFromVal(doublelist *head,int value) //按值删
{
if (head == NULL) exit(0);
doublelist *p = head;
doublelist *q = head->next;
while (q != NULL)
{
if (q->data == value)
{
if(q->next ==NULL) //删除尾结点
{
p->next = q->next;
}
else
{
p->next = q->next;
q->next->prior =p;
}
free(q);
q = p->next;
head->length--;
}
else
{
p = q;
q = q->next;
}
}
return true;
}
bool IsEmpty(doublelist* head) //判空
{
if (head == NULL) exit(0);
return head->length == 0;
}
int GetLength(doublelist* head) //长度
{
if(head==NULL) exit(0);
return head->length ;
}
void DestoryDoubleList(doublelist* head) //销毁
{
if (head == NULL) exit(0);
while (!IsEmpty(head))
{
DeleteDoubleListHead(head);
}
}
void Show(doublelist *head)
{
if(head==NULL) exit(0);
doublelist *p=head->next ;
printf("正向打印:\n");
while(p->next !=NULL)
{
printf("%d ",p->data );
p=p->next ;
}
printf("%d\n",p->data );
printf("逆向打印:\n");
while(p!=head)
{
printf("%d ",p->data );
p=p->prior ;
}
printf("\n");
}
int main()
{
doublelist head;
InitDoubleList(&head);
for(int i=1;i<6;i++)
{
InsertDoubleListHead(&head,i);
}
Show(&head);
printf("单链表长度:%d\n",GetLength(&head));
return 0;
}