引入
按照惯例,我们学习了如何初始化、插入、删除一个静态链表,那么静态链表打底有什么优缺点呢?链表还有什么高级玩法呢?
我们一起来看看~
静态链表的优缺点
- **优点:**插入和删除时,只需要求改游标,不需要移动元素,从而
改进了顺序存储结构中需要大量移动元素的缺点。 - **缺点:**没有解决连续存储分配带来得表长难以确定的问题。
总之,静态链表是一个很好的尝试,在没有动态创建、释放内存空间得情况下,利用数组,完成了静态链表。
练习
创建一个20个元素的动态链表,然后快速找到其中间结点。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LEN sizeof(struct Student)
#define STU_NUM 21
struct Student {
int num;
float score;
struct Student * next;
};
struct Student *create(){
srand((time(0)));
struct Student *a , *b , *head;
a=b=(struct Student *)malloc(LEN);
int n=0;
while(n<STU_NUM){
n=n+1;
a->num=n;
a->score=rand()%100+1;
if(n==1){
head=a;
}else{
b->next=a;
b=a;
}
a=(struct Student *)malloc(LEN);
}
b->next=NULL;
return head;
}
void print_stu(struct Student *stu_p){
while(stu_p!=NULL){
printf("%d号:%3.1f分\n",stu_p->num,stu_p->score);
stu_p=stu_p->next;
}
}
struct Student *mid_p(struct Student *stu_p){
struct Student *mid , *fast;
mid=fast=stu_p;
while(fast->next!=NULL){
if(fast->next->next!=NULL){
fast=fast->next->next;
mid=mid->next;
}else{
fast=fast->next;
}
}
return mid;
}
int main(){
struct Student *stu_p , *mid;
stu_p=create();
print_stu(stu_p);
mid=mid_p(stu_p);
printf("中间结点是%d号%3.1f分\n",mid->num,mid->score);
return 0;
}
运行结果
1号:49.0分
2号:69.0分
3号:12.0分
4号:6.0分
5号:45.0分
6号:3.0分
7号:40.0分
8号:74.0分
9号:67.0分
10号:27.0分
11号:83.0分
12号:89.0分
13号:84.0分
14号:26.0分
15号:61.0分
16号:68.0分
17号:77.0分
18号:87.0分
19号:63.0分
20号:84.0分
21号:45.0分
中间结点是11号83.0分
我们利用随机数,动态生成了链表,非常有趣的是,我们通过一个循环内移动两个指针,快速来快速遍历所有的链表,快速链表结束后,慢速指针就搞定了中间结点的位置。
尾巴
这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。
评论