双向链表定义
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。双向链表比单链表稍复杂, 也更不常用. 主要是为了练习链表的变种, 寻找更多设计的感觉. 这样在面对实际问题的时候, 就具有一定的建模能力。
双向链表操作
1.定义
typedef struct DoubleLinkedNode
{
char data;
struct DoubleLinkedNode *previous;
struct DoubleLinkedNode *next;
} DLNode, *DLNodePtr;
2.初始化
DLNodePtr initLinkList()
{
DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
tempHeader->data='\0';
tempHeader->previous=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 insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition)
{
DLNodePtr p, q, r;
//寻找插入位置
p = paraHeader;
for (int i = 0; i < paraPosition; i ++)
{
p = p->next;
if (p == NULL)//检查位置合理性
{
printf("位置%d超出链表范围\n",paraPosition);
return;
}
}
//创建新结点
q = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
q->data = paraChar;
//连接结点
r = p->next;
q->next = p->next;
q->previous = p;
p->next = q;
if (r != NULL)
{
r->previous = q;
}
}
5.按元素删除
void deleteElement1(DLNodePtr paraHeader, char paraChar)
{
DLNodePtr p, q, r;
p = paraHeader;
//寻找元素
while ((p->next != NULL) && (p->next->data != paraChar))//判断元素存在性
{
p = p->next;
}
//删除操作
printf("删除%c\r\n",paraChar);
if (p->next == NULL)
{
printf("元素%c不存在\r\n",paraChar);
return;
}
//删除操作
q = p->next;
r = q->next;
p->next = r;
if (r != NULL)
{
r->previous = p;
}
free(q);
}
6.按位置删除
int deleteElement2(DLNodePtr paraHeader,int paraPosition)
{
DLNodePtr p,q,r;
p=paraHeader;
printf("删除第%d个元素\r\n",paraPosition);
//寻找位置
for(int i=0;i<paraPosition-1;i++)
{
p=p->next;
if(p==NULL)
{
printf("位置%d超出链表范围\n",paraPosition);
return -1;
}
}
//删除操作
q=p->next;
r=q->next;
p->next=r;
if(r!=NULL)
{
r->previous=p;
}
free(q);
}
7.查找位置
int locateElement(DLNodePtr paraHeader,char paraChar)
{
int i=0;
DLNodePtr p=paraHeader->next;
while(p)
{
i++;
if(p->data==paraChar)
return i;
p=p->next;
}
return 0;
}
8.清空
void clearList(DLNodePtr paraHeader)
{
DLNodePtr p,q;
p=paraHeader->next;
while(p)
{
q=p->next;
free(p);
p=q;
}
paraHeader->next=NULL;
}
双向链表功能测试
void DoubleLinkListTest()
{
//初始化
DLNodePtr tempList=initLinkList();
printList(tempList);
//插入测试
insertElement(tempList,'C',0);
insertElement(tempList,'h',1);
insertElement(tempList,'i',2);
insertElement(tempList,'n',3);
insertElement(tempList,'e',4);
insertElement(tempList,'s',5);
insertElement(tempList,'e',6);
insertElement(tempList,'!',7);
printList(tempList);
//查找测试
printf("C是第%d位元素\r\n",locateElement(tempList,'C'));
printf("!是第%d位元素\r\n",locateElement(tempList,'!'));
//删除测试1
deleteElement1(tempList,'e');
printList(tempList);
deleteElement1(tempList,'i');
printList(tempList);
deleteElement1(tempList,'f');
printList(tempList);
//删除测试2
deleteElement2(tempList,3);
printList(tempList);
deleteElement2(tempList,11);
//清空测试
clearList(tempList);
printList(tempList);
}
插入测试
Chinese!
查找测试
C是第1位元素
!是第8位元素
删除测试1
删除e
Chinse!
删除i
Chnse!
删除f
元素f不存在
Chnse!
删除测试2
删除第3个元素
Chse!
删除第11个元素
位置11超出链表范围
清空测试
清空后链表:
总代码
#include <stdio.h>
#include <malloc.h>
//定义双向链表
typedef struct DoubleLinkedNode
{
char data;
struct DoubleLinkedNode *previous;
struct DoubleLinkedNode *next;
} DLNode, *DLNodePtr;
//初始化
DLNodePtr initLinkList()
{
DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
tempHeader->data='\0';
tempHeader->previous=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 insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition)
{
DLNodePtr p, q, r;
//寻找插入位置
p = paraHeader;
for (int i = 0; i < paraPosition; i ++)
{
p = p->next;
if (p == NULL)//检查位置合理性
{
printf("位置%d超出链表范围\n",paraPosition);
return;
}
}
//创建新结点
q = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
q->data = paraChar;
//连接结点
r = p->next;
q->next = p->next;
q->previous = p;
p->next = q;
if (r != NULL)
{
r->previous = q;
}
}
//按元素删除
void deleteElement1(DLNodePtr paraHeader, char paraChar)
{
DLNodePtr p, q, r;
p = paraHeader;
//寻找元素
while ((p->next != NULL) && (p->next->data != paraChar))//判断元素存在性
{
p = p->next;
}
//删除操作
printf("删除%c\r\n",paraChar);
if (p->next == NULL)
{
printf("元素%c不存在\r\n",paraChar);
return;
}
//删除操作
q = p->next;
r = q->next;
p->next = r;
if (r != NULL)
{
r->previous = p;
}
free(q);
}
//按位置删除
int deleteElement2(DLNodePtr paraHeader,int paraPosition)
{
DLNodePtr p,q,r;
p=paraHeader;
printf("删除第%d个元素\r\n",paraPosition);
//寻找位置
for(int i=0;i<paraPosition-1;i++)
{
p=p->next;
if(p==NULL)
{
printf("位置%d超出链表范围\n",paraPosition);
return -1;
}
}
//删除操作
q=p->next;
r=q->next;
p->next=r;
if(r!=NULL)
{
r->previous=p;
}
free(q);
}
//查找元素所在位置
int locateElement(DLNodePtr paraHeader,char paraChar)
{
int i=0;
DLNodePtr p=paraHeader->next;
while(p)
{
i++;
if(p->data==paraChar)
return i;
p=p->next;
}
return 0;
}
//整表删除
void clearList(DLNodePtr paraHeader)
{
DLNodePtr p,q;
p=paraHeader->next;
while(p)
{
q=p->next;
free(p);
p=q;
}
paraHeader->next=NULL;
}
void DoubleLinkListTest()
{
//初始化
DLNodePtr tempList=initLinkList();
printList(tempList);
//插入测试
insertElement(tempList,'C',0);
insertElement(tempList,'h',1);
insertElement(tempList,'i',2);
insertElement(tempList,'n',3);
insertElement(tempList,'e',4);
insertElement(tempList,'s',5);
insertElement(tempList,'e',6);
insertElement(tempList,'!',7);
printList(tempList);
//查找测试
printf("C是第%d位元素\r\n",locateElement(tempList,'C'));
printf("!是第%d位元素\r\n",locateElement(tempList,'!'));
//删除测试1
deleteElement1(tempList,'e');
printList(tempList);
deleteElement1(tempList,'i');
printList(tempList);
deleteElement1(tempList,'f');
printList(tempList);
//删除测试2
deleteElement2(tempList,3);
printList(tempList);
deleteElement2(tempList,11);
printList(tempList);
//清空测试
printf("清空后链表:");
clearList(tempList);
printList(tempList);
}
void main()
{
DoubleLinkListTest();
}