0%

顺序表与列表

顺序表

顺序表结构讲解

众所周知,数据结构=结构定义+结构操作,以下内容按这个思想去理解会更舒畅

顺序表可以类比成一个带有属性的数组(这里我不放图,可以自行去找图来理解)

顺序表结构定义三部分

  1. 一段连续的存储区域,用于顺序表存储元素
  2. 一个整形变量,用于标记顺序表的大小(size)
  3. 一个整形变量,用于标记顺序表中到底储存了多少个元素(count)

顺序表插入操作
0 1 2 3 4 5 6
[1] [2] [3] [4] [5] [6] [ ]

现在要在2这个位置插入一个6,那么要进行的操作就是把位置2到5的3456全部平行向后移一格

0 1 2 3 4 5 6
[1] [2] [6] [3] [4] [5] [6]

然后size不变,因为原来是7个的数组,现在还是
count要+1,因为多了一个元素
顺序表删除操作
0 1 2 3 4 5 6
[1] [2] [3] [4] [5] [6] [ ]
现在要在2这个位置把元素3删了,后面向前移一格,size不变,count-1

顺序表代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include<stdio.h>
#include<stdlib.h>//引入标准库,提供动态内存分配(malloc、free)、进程控制(exit)等函数的声明。
#include<time.h>
//先写结构定义
typedef struct vector {
int size,count;//按照前面说说的分别定义数据表的各个部分
int *data; //用data这个指针指向整型存储区
} vector;

//初始化操作
vector *getNewVector(int n){
vector *p=(vector *)malloc(sizeof(vector)); //分配内存空间,大小刚好能容纳一个 vector 结构体。
//malloc函数:在「堆(heap)」区动态分配一块指定字节数的连续内存空间,并返回这块空间的起始地址。
p->size=n;
p->count=0; //初始化计数器
p->data=(int *)malloc(sizeof(int)*n); //分配数据存储区,在堆上再分配一块 n * sizeof(int) 字节的空间,用来存放实际的整数元素。
return p; //返回指向新向量的指针
}

//插入操作
int insert(vector *v,int pos ,int val){
if(pos<0 || pos>v->count){ //检查位置是否合法
return 0; //位置不合法,返回0表示插入失败
}
if(v->size==v->count){
return 0;
}
//这里用逆序遍历来进行位移操作
for(int i=v->count-1;i>=pos;i--){
v->data[i+1]=v->data[i]; //将元素向后移动一位
}
v->data[pos]=val; //在空出的位置插入新元素
v->count++; //更新元素计数
return 1;
}

//输出操作
void printVector(vector *v){
int len=0;
for(int i=0;i<v->size;i++){
len+=printf("%3d",i);//计算第一行的输出的长度信息,方便第二行对齐
}
for(int i=0;i<len;i++){
printf("-");
}
printf("\n");
for(int i=0;i<v->count;i++){
printf("%3d",v->data[i]); //输出每个元素
}
printf("\n");
return ;
}
//删除操作
int erase(vector *v,int pos){
if(pos<0||pos>=v->count){
return 0;
}
//直接覆盖掉即可
for(int i=pos+1;i<v->count;i++){
v->data[i-1]=v->data[i]; //将后面的元素向前移动一位
}
v->count--; //更新元素计数
return 1;
}


//销毁操作
void clear(vector *v){
if(v==NULL){
return ;
}
free(v->data);//free(v->data) 会将这块动态分配的内存还给系统,解除它的分配状态。
free(v);//这一步将 vector 结构体对象本身的内存释放掉。通常在创建时,你会用 malloc(sizeof(vector)) 分配它,所以现在要成对地用 free 释放它
return ;
}

int main(){
srand(time(NULL)); //设置随机数种子
#define N 10
vector *v=getNewVector(N); //创建一个新顺序表
for(int i=0;i<N;i++){
int op=rand()%4,pos,val;
switch (op)
{
case 0:
case 1:
case 2:
pos=rand()%(v->count+1); //随机生成插入位置
val=rand()%100;
printf("insert %d at %d to vector=%d\n", val, pos,insert(v, pos, val));
break;
case 3:
pos=rand()%(v->count+1);
printf("erase %d from vector=%d\n", pos, erase(v, pos));
break;
}
printVector(v);
}
clear(v);
return 0;
}