摘要:在我们对单链表有一定认识并且掌握后,双链表其实是非常简单的,就是加了一个指向前一个结点的指针*previous,在我们进行插入删除等基础操作时,对比单链表只需要增加对previous的操作,稍加思考我们就可以比较容易的实现,所以我在看了老师的代码后跟着写了一个,代码里并没有太多注释。如有不懂的地方可以参考我以前单链表的文章,里面有十分详细的中文注释。
一.代码块
1)创建链表
typedef struct doubleLinkedList
{
char data;
struct doubleLinkedList *pre;
struct doubleLinkedList *next;
}DLNode,*DLNodePtr;
2)初始化链表
DLNodePtr doubleLinkedListInit()
{
DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(DLNode));
tempHeader->data = '\0';
tempHeader->pre = NULL;
tempHeader->next = NULL;
return tempHeader;
}
3)打印链表
void printList(DLNodePtr paraHeader)
{
DLNodePtr p = paraHeader->next;
while(p != NULL)
{
printf("%c",p->data);;
p = p->next;
}
printf("\r\n");
}
4)插入元素(指定位置插入)
void insertElementByPosition(DLNodePtr paraHeader,char paraChar,int paraPosition)
{
int i;
DLNodePtr p,q,r;
q = (DLNodePtr)malloc(sizeof(DLNode));
p = paraHeader;
for(i = 0;i < paraPosition;i ++)
{
p = p->next;
if(p == NULL)
{
printf("The position %d is beyond the scope of the list.", paraPosition);
return ;
}
}
q->data = paraChar;
if(p->next == NULL)
{
q->next = NULL;
q->pre = p;
p->next = q;
}
else
{
r = p->next;
r->pre = q;
q->next = r;
p->next = q;
q->pre = p;
}
}
这里我写代码分成了两种情况写,但实际上两种情况只有一句代码的差别,实际上像老师那样写代码量少,也容易看懂,所以我后面的删除就参考了老师的代码
5)删除指定元素
void deleteElement(DLNodePtr paraHeader,char paraChar)
{
DLNodePtr p, q, r;
p = paraHeader;
while((p->next != NULL) && (p->next->data != paraChar))
{
p = p->next ;
}
if(p->next == NULL)
{
printf("The char '%c' does not exist.\r\n", paraChar);
return ;
}
q = p->next;
r = q->next;
p->next = r;
if(r != NULL)
{
r->pre = p;
}
free(q);
}
6)删除指定位置的元素
void deleteElementByPosition(DLNodePtr paraHeader,int paraPosition)
{
int i;
DLNodePtr p,q,r;
p = paraHeader;
for(i = 0;i < paraPosition;i ++)
{
p = p->next;
if(p == NULL)
{
printf("The position %d is beyond the scope of the list.", paraPosition);
return ;
}
}
q = p->next;
r = q->next;
p->next = r;
if(r != NULL)
{
r->pre = p;
}
free(q);
}
实际上两种方法大同小异,差别就是如何帮助p跟随到正确的位置,后续的操作两种方法一样.
7)测试代码
void insertDeleteTest()
{
DLNodePtr tempList = doubleLinkedListInit();
insertElementByPosition(tempList, 'H', 0);
insertElementByPosition(tempList, 'e', 1);
insertElementByPosition(tempList, 'l', 2);
insertElementByPosition(tempList, 'l', 3);
insertElementByPosition(tempList, 'o', 4);
insertElementByPosition(tempList, '!', 5);
printList(tempList);
deleteElement(tempList, 'e');
deleteElement(tempList, 'a');
deleteElement(tempList, 'o');
printList(tempList);
insertElementByPosition(tempList, 'x', 1);
printList(tempList);
deleteElementByPosition(tempList, 0); //边界测试
printList(tempList);
deleteElementByPosition(tempList, 1); //正常测试
printList(tempList);
deleteElementByPosition(tempList, 2); //边界测试
printList(tempList);
}
二.插入和删除的图示
三.全部代码
#include <stdio.h>
#include <malloc.h>
typedef struct doubleLinkedList
{
char data;
struct doubleLinkedList *pre;
struct doubleLinkedList *next;
}DLNode,*DLNodePtr;
DLNodePtr doubleLinkedListInit()
{
DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(DLNode));
tempHeader->data = '\0';
tempHeader->pre = NULL;
tempHeader->next = NULL;
return tempHeader;
}
void printList(DLNodePtr paraHeader)
{
DLNodePtr p = paraHeader->next;
while(p != NULL)
{
printf("%c",p->data);;
p = p->next;
}
printf("\r\n");
}
void insertElementByPosition(DLNodePtr paraHeader,char paraChar,int paraPosition)
{
int i;
DLNodePtr p,q,r;
q = (DLNodePtr)malloc(sizeof(DLNode));
p = paraHeader;
for(i = 0;i < paraPosition;i ++)
{
p = p->next;
if(p == NULL)
{
printf("The position %d is beyond the scope of the list.", paraPosition);
return ;
}
}
q->data = paraChar;
if(p->next == NULL)
{
q->next = NULL;
q->pre = p;
p->next = q;
}
else
{
r = p->next;
r->pre = q;
q->next = r;
p->next = q;
q->pre = p;
}
}
void deleteElement(DLNodePtr paraHeader,char paraChar)
{
DLNodePtr p, q, r;
p = paraHeader;
while((p->next != NULL) && (p->next->data != paraChar))
{
p = p->next ;
}
if(p->next == NULL)
{
printf("The char '%c' does not exist.\r\n", paraChar);
return ;
}
q = p->next;
r = q->next;
p->next = r;
if(r != NULL)
{
r->pre = p;
}
free(q);
}
void deleteElementByPosition(DLNodePtr paraHeader,int paraPosition)
{
int i;
DLNodePtr p,q,r;
p = paraHeader;
for(i = 0;i < paraPosition;i ++)
{
p = p->next;
if(p == NULL)
{
printf("The position %d is beyond the scope of the list.", paraPosition);
return ;
}
}
q = p->next;
r = q->next;
p->next = r;
if(r != NULL)
{
r->pre = p;
}
free(q);
}
void insertDeleteTest()
{
DLNodePtr tempList = doubleLinkedListInit();
insertElementByPosition(tempList, 'H', 0);
insertElementByPosition(tempList, 'e', 1);
insertElementByPosition(tempList, 'l', 2);
insertElementByPosition(tempList, 'l', 3);
insertElementByPosition(tempList, 'o', 4);
insertElementByPosition(tempList, '!', 5);
printList(tempList);
deleteElement(tempList, 'e');
deleteElement(tempList, 'a');
deleteElement(tempList, 'o');
printList(tempList);
insertElementByPosition(tempList, 'x', 1);
printList(tempList);
deleteElementByPosition(tempList, 0); //边界测试
printList(tempList);
deleteElementByPosition(tempList, 1); //正常测试
printList(tempList);
deleteElementByPosition(tempList, 2); //边界测试
printList(tempList);
}
int main()
{
insertDeleteTest();
}
四.代码运行结果