写在前面:大家好,我是 花狗Fdog ,来自内蒙古的一个小城市,目前在泰州读书。很感谢能有这样一个平台让我能够在这里分享所学所感。我喜欢编程,喜欢代码,喜欢去做一个程序员。努力学习,争取多年后,给亲人更好的生活。
文章目录
- 双向链表图示
- 1.定义链表
- 2.初始化头尾结点
- 3.初始化链表结点
- 4.插入操作
- (1)图示
- (2)代码
- 5.遍历操作
- 6.删除操作
- 7.int main()操作
- 8.切记申请的内存记得要释放哦!!!
双向链表图示
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
1.定义链表
typedef struct Node
{
int data;
struct Node * prior;
struct Node * next;
}Node;
2.初始化头尾结点
Node * InitListHead()
{
Node * Head = (Node *)malloc(sizeof(Node));
Head->data = 0;
Head->next = NULL;
Head->prior = NULL;
return Head;
}
Node * InitListEnd()
{
Node * End = (Node *)malloc(sizeof(Node));
End->data = 0;
End->next = NULL;
End->prior = NULL;
return End;
}
3.初始化链表结点
void CreateCLinkList(Node ** Head,Node ** End,int a)//创建节点
{
//尾插法
Node * P = (Node *)malloc(sizeof(Node));
P->data = a;
if ((*Head)->next == NULL)
{
(*Head)->next = P;
P->prior = (*Head);
}
else
{
(*End)->prior->next = P;
P->prior = (*End)->prior;
}
P->next = (*End);
(*End)->prior = P;
(*Head)->data++;
}
4.插入操作
(1)图示
(2)代码
int InsertList(Node ** Head, Node ** End,int i,int num)//i为插入位置
{
//我们可以在头结点的数据存储链表长度,来判断插入位置是否合法,这里假定输入的i合法
//因为有首尾链表,我们可还以判断输入位置在前半部分,还是后半部分,从而选择使用头节点还是尾节点,这里就不做示范了
j = 0;
Node *Phead = (*Head);
Node *Pend = (*End);
Node * P = (Node *)malloc(sizeof(Node));
P->data = num;
if (i > (*Head)->data)
return 0;
//正向操作
//while (Phead != NULL)
//{
// if (i == j+1)
// {
// Phead->next->prior = P;
// P->next = Phead->next;
// Phead->next = P;
// P->prior = Phead;
// (*Head)->data++;
// }
// Phead = Phead->next;
// j++;
//}
//这不是我们今天的重点 今天的重点是 双向链表的逆向操作:
while (Pend->prior != NULL)
{
if (Phead->data - i == j)
{
P->prior = Pend->prior;
Pend->prior->next = P;
P->next = Pend;
Pend->prior = P;
(*Head)->data++;
return 0;
}
Pend = Pend->prior;
j++;
}
return 0;
}
5.遍历操作
void printList(Node * Head, Node * End)
{
//双向链表的遍历条件是头指针是否等于尾节点,或者是指针是否为空
Node * Phead = Head->next;
Node * Pend = End->prior;
//正向操作
//while (Phead->next != NULL)
//{
// printf("第一种 %d\n", Phead->data);
// Phead = Phead->next;
//}
//printf("\n");
//Node * Phead_1 = Head->next;
//while (Phead_1 != Pend)
//{
// printf("第二种 %d\n", Phead_1->data);
// Phead_1 = Phead_1->next;
//}
//同样这也是正向操作,下面来看逆向操作
while (Pend->prior != NULL)
{
printf("第一种 %d\n", Pend->data);
Pend = Pend->prior;
}
printf("\n");
}
6.删除操作
int DelList(Node ** Head, Node ** End, int i)
{
j = 0;
Node *Phead = (*Head);
Node *Pend = (*End);
Node * P = NULL;
if (i > (*Head)->data)
return 0;
//正向操作
//while (Phead->next != NULL)
//{
// if (i == j + 1)
// {
// P = Phead->next;
// Phead->next = Phead->next->next;
// Phead->next->prior = Phead;
// P->next = NULL;
// P->prior = NULL;
// free(P);
// (*Head)->data--;
// }
// Phead = Phead->next;
// j++;
//}
//同样,我们来看逆向操作:
while (Pend->prior != NULL)
{
if (Phead->data - i == j+1 )
{
P = Pend->prior;
Pend->prior->next = Pend;
Pend->prior = Pend->prior->prior;
P->next = NULL;
P->prior = NULL;
free(P);
(*Head)->data--;
}
Pend = Pend->prior;
j++;
}
return 0;
}
7.int main()操作
int main()
{
int j=0;
Node * Head = InitListHead();
Node * End = InitListEnd();
Node ** PH = &Head;
Node ** PE = &End;
for (int i = 1; i <= 10; i++)
{
CreateCLinkList(PH, PE, i);
}
printList(Head, End);
InsertList(PH, PE, 3, 99);
printList(Head, End);
DelList(PH, PE, 3);
printList(Head, End);
return 0;
}
8.切记申请的内存记得要释放哦!!!
若有错误。欢迎批评指出,欢迎交流。
每文一句:生命中,不断地有人离开或进入。于是,看见的,看不见了;记住的,以往了。生命中,不断地有得到或失落。于是看不见的,看见了;以往的,记住了,然而,看不见的,是不是就等于不存在?记住的,永远不会消失?