线性表
定义:线性表是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。线性表中数据元素的>关系是一对一的。
分类:顺序表、链表、栈和队列。
顺序表
定义: 是一种数据结构,结构是将数据依次放在地址连续的存储单元中。
特点:
存储元素的地址连续;。
可以通过对首地址的偏移访问所有元素
数组实现顺序表
全局变量及宏定义设置
#include <stdio.h>
int arr[100] = {0};
int len = 0;
末尾增加元素
void add(int val)
{
arr[len] = val;
len++;
}
删除指定元素
void del(int data)
{
for(int j = 0; j < len; j++) {
if(arr[j] == data) {
for(int k = j+1; k <= len-1; k++)
arr[k - 1] = arr[k];
len--;
j--;//防止连续多个相同的data在一起导致漏删;还可以通过倒序遍历的方法避免
}
}
}
输出顺序表
void print(void)
{
for(int j = 0; j < len; j ++)
printf("%d\t", arr[j]);
printf("\n");
}
修改指定元素为另外的值
void change(int val, int data)//val为指定要修改的元素,data为修改后的元素
{
for(int j = 0; j < len; j++)
if(arr[j] == val)
arr[j] = data;
}
查找指定元素,并返回下标(只能找到第一个位置)
int find(int data)
{
for(int j = 0; j < len; j++)
if(arr[j] == data)
return j;
return -1;//当没有找到指定元素时返回-1,表示该元素不存在
}
主函数
int main()
{
add(1); add(2); add(3); add(4); add(5);
print();
return 0;
}
指针实现顺序表
头文件及宏定义
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int Type;
创建一个顺序表
返回首地址创建顺序表
Type* initArr(int* max)
{
*max = 10;//设置顺序表的最大容量
Type* temp = (Type*)malloc((*max) * sizeof(Type));
memset(temp, 0, (*max) * sizeof(Type));//将申请的内存按字节初始化为0
return temp;
}
对应的main函数
int main()
{
Type* arr = NULL;
int maxSize = 0;
int len = 0;
arr = initArr(&maxSize);
return 0;
}
通过二级指针修改首地址的指向
void initArr(Type** buf, int* max)
{//buf为指向顺序表首地址的二级指针,*max为顺序表的最大容量
*max = 10;
*buf = (Type*)malloc((*max) * sizeof(Type));
memset(*buf, 0, (*max) * sizeof(Type));
}
对应的main函数
int main()
{
Type* arr = NULL;
int len = 0;
int maxSize = 0;
initArr(&arr, &maxSize);
return 0;
}
顺序表末尾增加元素
void add(Type** buf, int* len, int* max, Type val)
{//buf为指向顺序表首地址的二级指针,*len为顺序表的长度,*max为顺序表的最大长度,val为要增加的元素
if(*len < *max) {
(*buf)[*len] = val;
(*len)++;
} else {
*max = *max + *max / 2;//扩容为1.5倍
Type* temp = (Type*)malloc((*max) * sizeof(Type));//申请内存
for(int j = 0; j < *len; j++)
temp[j] = (*buf)[j];//将原来的数据复制到temp中
free(*buf);//释放原来的内存
*buf = temp;//重新指向空间足够的动态数组
(*buf)[*len] = val;
(*len)++;
}
}
输出顺序表
void print(Type* buf, int len)
{//tmp为顺序表首地址,len为顺序表长度
for(int j = 0; j < len; j++)
printf("%d\t", buf[j]);
printf("\n");
}
删除指定元素
void del(Type* buf, int* len, Type val)
{//buf为顺序表的首地址,*len为顺序表的长度,val为指定要删除的元素
for(int j = 0; j < *len; j++) {
if(buf[j] == val)
for(int k = j + 1; k < *len; k++)
buf[k - 1] = buf[k];
*len--;
j--;
}
}
修改指定元素
void change(Type* buf, int len, Type val, Type data)
{//buf为顺序表首地址,len为顺序表长度,val为要被修改的顺序表元素,data为修改之后的顺序表元素
for(int j = 0; j < len; j++)
if(buf[j] == val)
buf[j] = data;
}
查找指定元素
int find(Type* buf, int len, Type val)
{
for(int j = 0; j < len; j++)
if(buf[j] == val)
return j;
return -1;//当顺序表中找不到该指定元素时返回-1,表示该元素不存在
}
主函数
int main()
{
Type* arr = NULL;
int len = 0;
int maxSize = 0;
//arr = initArr(&maxSize)
initArr(&arr, &maxSize);
add(&arr, &len, &maxSize, 1);
add(&arr, &len, &maxSize, 4);
add(&arr, &len, &maxSize, 3);
add(&arr, &len, &maxSize, 3);
add(&arr, &len, &maxSize, 2);
add(&arr, &len, &maxSize, 2);
add(&arr, &len, &maxSize, 3);
print(arr, len);
return 0;
}
结构体实现顺序表
头文件及宏定义
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 100
typedef int Type;
typedef struct sequence {
Type* buf;//buf为顺序表首地址
int maxSize;//maxSize为顺序表当前最大容量
int len;//len为顺序表当前实际长度
} seq;//seq是一个顺序表对象
创建一个顺序表
通过二级指针初始化顺序表的结构体
void initArr(seq** seq1)
{//seq1指向一个顺序表对象
*seq1 = (seq*)malloc(sizeof(seq));
(*seq1)->len = 0;
(*seq1)->maxSize = MAXSIZE;
(*seq1)->buf = (Type*)malloc((*seq1)->maxSize * sizeof(Type));
memset((*seq1)->buf, 0, (*seq1)->maxSize * sizeof(Type));
}
对应的main函数
int main()
{
seq* arr1 = NULL;
initArr(&arr1);
printf("%d\n", arr1->maxSize);
return 0;
}
在main函数里初始化结构体再传入结构体地址创建
void initArr(seq* seq1)
{//seq1指向一个顺序表对象
seq1 = (seq*)malloc(sizeof(seq));
seq1->len = 0;
seq1->maxSize = 100;
seq1->buf = (Type*)malloc(seq1->maxSize * sizeof(Type));
memset(seq1->buf, 0, seq1->maxSize * sizeof(Type));
}
对应的main函数
int main()
{
seq arr1 = {
.buf = NULL,
.len = 0,
.maxSize = 0
};
initArr(&arr1);
printf("%d\n", arr1.buf[0]);
return 0;
}
增加一个指定元素
void add(seq* seq1, Type val)
{//seq1指向一个顺序表对象
if(seq1->len >= seq1->maxSize) {
seq1->maxSize = seq1->maxSize + seq1->maxSize / 2;//扩容为原先的1.5倍
Type* temp = (Type*)malloc(seq1->maxSize * sizeof(Type));//临时指针作为扩容后顺序表首地址
for(int j = 0; j < seq1->len; j++)
temp[j] = seq1->buf[j];
free(seq1->buf);//复制完成后释放原来的内存
seq1->buf = temp;//指向新的内存
seq1->buf[seq1->len] = val;
seq1->len++;
} else {
seq1->buf[seq1->len] = val;
seq1->len++;
}
}
输出顺序表
void print(seq* seq1)
{//seq1指向一个顺序表对象
for(int j = 0; j < seq1->len; j++)
printf("%d\t", seq1->buf[j]);
printf("\n");
}
删除指定元素
void del(seq* seq1, Type val)
{//seq1指向一个顺序表对象
for(int j = 0; j < seq1->len; j++) {
if(seq1->buf[j] == val) {
for(int k = j + 1; k < seq1->len; k++)
seq1->buf[k - 1] = seq1->buf[k];
seq1->len--;
j--;
}
}
}
修改元素
void change(seq* seq1, Type val, Type data)
{//seq1指向一个顺序表对象,val为要被修改的顺序表元素,data为修改之后的顺序表元素
for(int j = 0; j < seq1->len; j++) {
if(seq1->buf[j] == val) {
seq1->buf[j] = data;
}
}
}
查找指定元素
int* find(seq* seq1, Type val)
{//seq1指向一个顺序表对象
int* flag = (int*)malloc(seq1->len * sizeof(int));//flag为指定元素下标构成的动态数组
int i = 0;
for(int j = 0; j < seq1->len; j++) {
if(seq1->buf[j] == val) {
flag[i] = j;
i++;
}
}
if(i == 0)
return NULL;//如果没有指定元素返回NULL,表示顺序表内没有该元素
else
return flag;//返回值是动态数组的首地址
}