目录
双链表
下面是双向链表,而对于双向循环链表来讲,将头节点指针指向尾节点,尾节点指针指向头节点即可。此双向链表的头节点同单链表一样,不存有数据。
没学过的建议跳过,这一篇解释并不详细。对指针不了解的话看着可能很难受。
结构体定义
typedef struct node
{
int data;
struct node* next;
struct node* previous;
}NODE;
双链表创建
NODE* creat()
{
NODE* head, * p, * q;
head =(NODE*) malloc(sizeof(NODE));
if (!head)
return NULL;
head->previous = head;
head->next = NULL;
p = head;
while (1)
{
int t = 0;
printf("输入一个正整数(以负数结束):");
scanf_s("%d", &t);
if (t < 0)
break;
q =(NODE*)malloc(sizeof(NODE));
if (!q)
return NULL;
q->data = t;
q->previous = p;
p->next = q;
q->next = NULL;
p = q;
}
return head;
}
双链表节点删除
void dele(NODE* head, int t)
{
if (!head->next)
{
printf("该链表为空\n");
return;
}
while (head->next->data != t && head->next != NULL)
head = head->next;
if (!head->next)
printf("链表无此值");
else
head->next = head->next->next;
}
双链表显示
void print(NODE* p)
{
if (!p->next)
printf("该链表为空!\n");
else
{
printf("链表中的数据为:\n");
while (p->next != NULL)
{
printf("<-->%d", p->next->data);
p = p->next;
}
printf("\n");
}
}
双链表末尾加节点
void add(NODE* head, int value) //尾插
{
NODE* thisadd = (NODE*)malloc(sizeof(NODE));
if (!thisadd)
return;
else
thisadd->data = value;
while (head->next != NULL)
head = head->next;
thisadd->next = head->next;
head->next = thisadd;
thisadd->previous = head;
}
总代码块
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct node
{
int data;
struct node* next;
struct node* previous;
}NODE;
NODE* creat()
{
NODE* head, * p, * q;
head =(NODE*) malloc(sizeof(NODE));
if (!head)
return NULL;
head->previous = head;
head->next = NULL;
p = head;
while (1)
{
int t = 0;
printf("输入一个正整数(以负数结束):");
scanf_s("%d", &t);
if (t < 0)
break;
q =(NODE*)malloc(sizeof(NODE));
if (!q)
return NULL;
q->data = t;
q->previous = p;
p->next = q;
q->next = NULL;
p = q;
}
return head;
}
void print(NODE* p)
{
if (!p->next)
printf("该链表为空!\n");
else
{
printf("链表中的数据为:\n");
while (p->next != NULL)
{
printf("<-->%d", p->next->data);
p = p->next;
}
printf("\n");
}
}
void dele(NODE* head, int t)
{
if (!head->next)
{
printf("该链表为空\n");
return;
}
while (head->next->data != t && head->next != NULL)
head = head->next;
if (!head->next)
printf("链表无此值");
else
head->next = head->next->next;
}
void add(NODE* head, int value) //尾插
{
NODE* thisadd = (NODE*)malloc(sizeof(NODE));
if (!thisadd)
return;
else
thisadd->data = value;
while (head->next != NULL)
head = head->next;
thisadd->next = head->next;
head->next = thisadd;
thisadd->previous = head;
}
int main()
{
NODE* h;
h = creat();
print(h);
while (1)
{
int data = 0;
printf("请输入待删除结点的值(以负数结束):");
scanf_s("%d", &data);
if (data < 0)
break;
dele(h, data);
print(h);
}
while (1)
{
int data = 0;
printf("请输入增加尾结点的值(以负数结束):");
scanf_s("%d", &data);
if (data < 0)
break;
add(h, data);
print(h);
}
return 0;
}
结果
单链表的反向
结构体定义
typedef struct node
{
int data;
struct node* next;
}NODE;
单链表创建
NODE* creat()
{
NODE* head, * p, * q;
int t = 0;
head = malloc(sizeof(NODE));
if (!head)
return NULL;
p = head;
while (1)
{
printf("输入一个正整数(以负数结束):");
scanf_s("%d", &t);
if (t < 0)
break;
q = malloc(sizeof(NODE));
if (!q)
return NULL;
q->data = t;
p->next = q;
p = q;
}
p->next = NULL;
return head;
}
单链表遍历
void print(NODE* p)
{
if (!p->next)
{
printf("该链表为空!\n");
return;
}
else
{
printf("链表中的数据为:\n");
while (p->next)
{
printf("->%d", p->next->data);
p = p->next;
}
printf("\n");
}
}
单链表的逆转
以上示意图假设每个结构体都有值。首先把old_head指向的第一个节点复制给New_head,在这次循环后,让Old_head指向下一个节点,New_head指向已经旋转的节点。
while (OldHead)
{
temp = OldHead->next;
OldHead->next = NewHead;
NewHead = OldHead;
OldHead = temp;
}
以上循环的主体部分,将old_head指向的第一个节点插入到New_head头上,同时更新oldhead和Newhead的值。当将old_head指向的第一个节点插入到New_head头上时,我们需要知道oldhead的下一个节点,因此创建一个临时变量temp。
以上思想的本质是我们将单链表看成一个一个独立的单元,然后像我们折莲藕一样,把一节一节的部分从头到尾变成从尾到头。
经过以上循环,此时的newhead组成的单链表并不符合单链表的初始定义。因此,重新创建一个结构体指针插入为其头节点。
NODE* Reverse(NODE* L)
{
assert(L);
NODE* NewHead, *OldHead, *temp;
OldHead = L->next;
NewHead = NULL;
while (OldHead)
{
temp = OldHead->next;
OldHead->next = NewHead;
NewHead = OldHead;
OldHead = temp;
}
NODE* CreatHead = (NODE*)malloc(sizeof(NODE));
if (!CreatHead)
{
printf("头节点创建失败!!!");
L = NewHead;
printf("打印出来的头节点数据已经丢失");
}
else
{
CreatHead->next = NewHead;
L = CreatHead;
}
return L;
}
总代码
#include <stdlib.h>
#include <assert.h>
typedef struct node
{
int data;
struct node* next;
}NODE;
NODE* creat()
{
NODE* head, * p, * q;
int t = 0;
head = malloc(sizeof(NODE));
if (!head)
return NULL;
p = head;
while (1)
{
printf("输入一个正整数(以负数结束):");
scanf_s("%d", &t);
if (t < 0)
break;
q = malloc(sizeof(NODE));
if (!q)
return NULL;
q->data = t;
p->next = q;
p = q;
}
p->next = NULL;
return head;
}
void print(NODE* p)
{
if (!p->next)
{
printf("该链表为空!\n");
return;
}
else
{
printf("链表中的数据为:\n");
while (p->next)
{
printf("->%d", p->next->data);
p = p->next;
}
printf("\n");
}
}
NODE* Reverse(NODE* L)
{
assert(L);
NODE* NewHead, *OldHead, *temp;
OldHead = L->next;
NewHead = NULL;
while (OldHead)
{
temp = OldHead->next;
OldHead->next = NewHead;
NewHead = OldHead;
OldHead = temp;
}
NODE* CreatHead = (NODE*)malloc(sizeof(NODE));
if (!CreatHead)
{
printf("头节点创建失败!!!");
L = NewHead;
printf("打印出来的头节点数据已经丢失");
}
else
{
CreatHead->next = NewHead;
L = CreatHead;
}
return L;
}
int main()
{
NODE* h;
h = creat();
print(h);
NODE*h1=Reverse(h);
print(h1);
return 0;
}