之前我已经大致说明了堆栈的概念及特点,这次,我们用一种更加简单直观的方式将一个链表按逆序排列。
#include<stdio.h>
#include<stdlib.h>
struct line
{
int num;
struct line *next;
} *p1, *p2;
struct line *creat()
{
int temp;
struct line *head = NULL;
printf("\n请输入链表(非表示结束)\n结点值:");
while (scanf("%d", &temp))
{
p1 = (struct line *)malloc(sizeof(struct line));
(head == NULL) ? (head = p1) : (p2->next = p1);
p1->num = temp;
printf("结点值:");
p2 = p1;
}
p2->next = NULL;
return head;
}
output(struct line *outhead)
{
for (p1 = outhead; p1 != NULL; printf("%4d", p1->num), p1 = p1->next);
}
struct line *turnback(struct line *head)
{
struct line *new, *newhead = NULL;
do
{
p2 = NULL;
p1 = head;
while (p1->next != NULL)
{
p2 = p1;
p1 = p1->next;
}
if (newhead == NULL)
{
newhead = p1;
new = newhead->next = p2;
}
new = new->next = p2;
p2->next = NULL;
}
while (head->next != NULL);
return newhead;
}
int main(void)
{
struct line *head;
head = creat();
printf("\n原来表:\n");
output(head);
head = turnback(head);
printf("\n\n反转表:\n");
output(head);
return 0;
}
code::blocks运行结果:
对于链表:
插入操作处理顺序:中间节点的逻辑,后节点逻辑,前节点逻辑。按照这个顺序处理可以完成任何链表的插入操作。
删除操作的处理顺序:前节点逻辑,后节点逻辑,中间节点逻辑。按照此顺序可以处理任何链表的删除操作。
如果不存在其中的某个节点略过即可。
大家可以看到一个现象,就是插入的顺序和删除的顺序恰好是相反的。
其他:
单向链表是基本知识,学会了单向链表的操作,双向链表与循环链表就是在单向链表的基础上增加了对链头与链尾的衔接。
在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点地址,一个存储直接前驱结点地址。定义结构体时含有两个指针变量。
在循环链表中,最后一个结点的指针是指向该循环链表的第一个结点或者表头结点,从而构成一个环形的链。