【申明:本文仅限于自我归纳总结和相互交流,有纰漏还望各位指出。 联系邮箱:Mr_chenping@163.com】
前几天写了一个单向链表,今天参考自己单向链表改写了一个双向非循环链表,下面只讨论双向非循环链表。
双向非循环链表有如下特点:
一、双向链表每个结点都有一个前驱指针和后驱指针(当然头结点和尾结点除外)。
二、双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
三、头结点只有后驱指针没有前驱指针,尾结点后驱指针指向NULL。
一、初始化数据结构
/*定义双向链表结构*/
typedef struct _Double_Link_Node
{
int Data;
struct _Double_Link_Node *prev;
struct _Double_Link_Node *next;
}Double_Link_Node;
二、创建一个头结点
/*创建一个双向链表,返回一个空结点*/
Double_Link_Node *Create_Double_Link()
{
Double_Link_Node *New;
New = (Double_Link_Node*)malloc(sizeof(Double_Link_Node));
if(NULL == New)
{
perror("creat malloc");
}
New->Data = 0;
New->prev = NULL;
New->next = NULL;
return New;
}
三、向双向链表中插入一个节点(顺序插入)
/*插入结点*/
int Insert_Note(Double_Link_Node *head, int value)
{
Double_Link_Node *current = head;
Double_Link_Node *New;
New = (Double_Link_Node*)malloc(sizeof(Double_Link_Node));
if(NULL == New)
{
perror("insert malloc");
return -1;
}
New->Data = value;
while((current->next != NULL) && (value > current->next->Data))
{
current = current->next;
}
if(current->next == NULL) /*为空或者查找到最后插入*/
{
if(head->next == NULL)
{
current->next = New;
New->prev = NULL;
New->next = NULL;
}
else
{
current->next = New;
New->prev = current;
New->next = NULL;
}
}
else
{
current->next->prev = New;
New->next = current->next;
New->prev = current;
current->next = New;
}
return 0;
}
四、删除节点(顺序查找到后删除)
/*删除节点*/
int Delete_Note(Double_Link_Node *head, int valude)
{
Double_Link_Node *current = head->next;
while((current != NULL) && (current->Data != valude))
{
current = current->next;
}
if(current == NULL) //等于NULL有两种情况:(1)查找到最后、(2)节点为空
{
if(head->next == NULL)
{
printf("The Double List is empty!\n");
}
else
{
printf("Not find the Node!\n");
}
return -1;
}
else
{
if(current->prev == NULL) //第一个结点
{
head->next = current->next;
current->next->prev = NULL;
}
else if(current->next == NULL) //最后一个节点
{
current->prev->next = NULL;
current->prev = NULL;
}
else //中间删除
{
current->prev->next = current->next;
current->next->prev = current->prev;
}
free(current);
printf("Delete Node success!\n");
}
return 0;
}
五、查找节点
/*查找指定节点*/
int Search_Link(Double_Link_Node *head, int key)
{
Double_Link_Node *current = head->next;
while((current != NULL) && (current->Data != key))
{
current = current->next;
}
if(current == NULL) //链表为空或者没有查找到
{
if(head->next == NULL)
{
printf("The Double Link is empty!\n");
}
else
{
printf("Not find the Node!\n");
}
return -1;
}
else
{
printf("find it!\n");
}
return 0;
}
六、测定结点个数
/*测链表长度*/
int Length_Link(Double_Link_Node *head)
{
int count=0;
Double_Link_Node *current=head->next;
while(current != NULL)
{
count++;
current = current->next;
}
return count;
}
七、释放链表
/*释放链表*/
void Free_Link(Double_Link_Node *head)
{
Double_Link_Node *current = head->next;
Double_Link_Node *record = head;
while(current != NULL)
{
record = current;
current = current->next;
free(record);
}
free(head);
printf("Free Link success!");
exit(0);
}
八、遍历输出链表(有反向输出,检查前驱指针是否连接好)
/*打印链表*/
void Print_Link(Double_Link_Node *head)
{
Double_Link_Node *current = head->next;
printf("\nLink as fallows:\n");
while(current != NULL)
{
printf("%d<==>", current->Data);
current = current->next;
}
printf("\n");
}
void Print_Link(Double_Link_Node *head)
{
printf("\nLink as fallows:\n");
if(head->next != NULL)
{
Double_Link_Node *current = head;
while(current->next != NULL)
{
//printf("%d<==>", current->Data);
current = current->next;
}
while(current != head->next)
{
printf("%d<==>", current->Data);
current = current->prev;
}
printf("%d<==>", current->Data);
}
printf("\n");
}
调用接口没有给出,可以自己写。。也可以参考我上次写的单向链表接口。