最近有点忙,今天才开始看数据结构单链表的部分,由于考研,看了《王道复习指导书》上只讲了带头结点的单链表操作,只是文末提了下不带头节点的什么情况,在此结合王道复习书,电脑上写了运行了下不带头结点的。
//
// Created by gxj on 2021/3/30.
//
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
//单链表结构体,LNode表示结点,LinkList表示链表,其实两者一样的,只是表示不同
typedef struct LNode {
ElementType data;
struct LNode *next;
} LNode, *LinkList;
//不带头节点头插法
void NoNode_HeadInsert(LinkList *L) {
//初始化链表
LNode *s;//要插入的节点
ElementType x;//要插入的元素
scanf("%d", &x);
while (x != 999) {
s = (LNode *) calloc(1, sizeof(LNode));
s->data = x;
s->next = NULL;
if (NULL == *L) {
*L = s;//将新结点置位首节点也是尾结点
} else {
s->next = *L;
*L = s;//新结点置位尾结点
}
scanf("%d", &x);
}
}
//不带头节点尾插法
void NoNode_TailInsert(LinkList *L) {
ElementType x;//要插入的元素
LNode *s;//要插入的节点
LNode *r;//尾指针
scanf("%d", &x);
while (x != 999) {
s = (LNode *) calloc(1, sizeof(LNode));
s->data = x;
s->next = NULL;
//链表是否为空
if (NULL == *L) {
*L = s;//将新结点置位首节点也是尾结点
r = *L;
} else {
r->next = s;
r = s;//新结点置位尾结点
}
scanf("%d", &x);
}
}
//链表输出
void NoNode_Print(LinkList L) {
while (L) {
printf("%3d", L->data);
L = L->next;
}
printf("\n");
fflush(stdout);
}
//链表逆置
LinkList reverse_LinkList(LinkList L){
LinkList newList = NULL;
LNode *s;
while(L){
s = (LNode *) calloc(1, sizeof(LNode));
s->data = L->data;
s->next = NULL;
if (NULL == newList) {
newList = s;//将新结点置位首节点也是尾结点
} else {
s->next = newList;
newList = s;//新结点置位尾结点
}
L = L->next;
}
return newList;
}
int main() {
LinkList L = NULL;//空链表初始化
// NoNode_HeadInsert(&L);//不带头节点头插法
NoNode_TailInsert(&L);//不带头结点尾插法
NoNode_Print(L);//链表打印
LinkList newList = reverse_LinkList(L);//链表逆置
NoNode_Print(newList);//链表逆置后打印
return 1;
}
效果如下:
头插法(看图皆可以看出头插法他有链表的逆反的作用)
尾插法
单链表借助新的链表的逆置