链表
是一种最为基础的数据结构。链表是一组元素以一种特定的顺序组合或链接在一起。在维护数据的集合时很有用。链表在执行插入和删除操作时,拥有更高的效率。链表需要动态的开辟储存空间,也就是在程序运行时分配。
链表包括:
单链表,双向链表,循环链表。
首先学习较为简单的单链表。
尤其注意,单链表一定只能从头开始遍历。
单链表包括数据成员和结构指针,指向下一个节点。
元素实际上都是分散在内存空间的,元素与元素之间的链接关系只是为了确保所有的元素都可以访问到!
1、程序的开头。
运用宏定义int类型可以在后面更改数据类型的时候快速更改。
linklist是一个结构指针,lnode是一个用于开辟内存空间所用的变量名。
#include <stdio.h>
#include <stdlib.h>
#define ERROR 0
#define Ok 1
typedef int elemtype;
typedef int status;
typedef struct structure {
elemtype data;
struct structure *next;
} lnode, *linklist;
2、准备工作
为定义的链表一定要初始化为null。
int main() {
linklist l;
l = (linklist)malloc(sizeof(lnode));
l->data = -1;
l->next = NULL;
}
3、建立一个带头节点的链表
void build(linklist l) {
linklist p, q;
printf("please input the total number of what you wanna input\n");
int n;
scanf("%d", &n);
p = l;
while (n--) {
q = (linklist)malloc(sizeof(lnode));
scanf("%d", &q->data);
q->next = NULL;
p->next = q;
p = q;//把q的地址给p,从而节点向下移动
}
}
4、输出一个链表
void print(linklist l) {
linklist p;
p = l->next;
while (p) {
printf("%d", p->data);
p = p->next;//推进
}
printf("\n");
}
5、给定一个值输出它的上一个值(假定给定的值一定在链表中)
近似于循环链表
void find_the_front_one(linklist l, int x) {
linklist p;
p = l;
while (p->next && p->next->data != x) {
p = p->next;
}
if (p->next->data == l->next->data) {//判断是否为第一个值
while (p->next) {
p = p->next;
}//推进到最后一个值
printf("%d\n", p->data);
return;
}
if (p->next) {
printf("%d\n", p->data);
}
}
6、给定一个值输出该值的下一个值(假定存在)
近似于循环链表
void find_the_next_one(linklist l, int x) {
linklist p;
p = l;
while (p && p->data != x) {
p = p->next;
}
if (p->next) {
printf("%d\n", p->next->data);
} else {
printf("%d\n", l->next->data);
}
}
7、删除链表大于mink并且小于maxk的值,前提是要已经排好序的!
void delete_the_mink_and_the_maxk(Linklist L) {
int maxk, mink;
Linklist p, q, s;
printf("请输入mink,maxk:\n");
scanf("%d %d",&mink,&maxk);
p = L;
while (p->next && p->next->data <= mink) {
p = p->next;
}
s = p->next;//s充当桥梁的作用
while (s && s->data < maxk) {
q = s;
s = s->next;
free(q);//删除节点
}
p->next = s;
printf("finished!\n");
p = L;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
8、排序
void Insert(Linklist L, Linklist p) {//在升序链表插入值为X的结点,使仍然有序
Linklist s;
s = L;
while (s->next && s->next->data < p->data) {
s = s->next;
}
p->next = s->next;
s->next = p;
}
//对于直接输入值要先申请变量!
//p = (LinkList)malloc(sizeof(LNode));
//p->data = x;
status sort(Linklist L) {//排序
Linklist s, r;
s = L->next;
L->next = NULL;
while (s) {
r = s;
s = s->next;
r->next = NULL;
Insert(L, r);
}
return Ok;
}
9、倒置
画图理解!
void daozhi(Linklist L) {
Linklist p, s;
p = s = L->next;
L->next = NULL;//指向链表的尾部
while (p) {
s = s->next;
p->next = L->next;
L->next = p;
p = s;
}//s相当于一个桥梁
printf("finished!!\n");
p = L->next;
while (p) {
printf("%d ", p->data);
p = p->next;
}//输出完成倒置后的链表
printf("\n");
}