数据结构(一)顺序表的相关操作

以下是我在学习 顺序表 及其相关接口操作时写的代码:

1.函数定义的 .c 文件

#include "SequenceList.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

//O(n)
//static 修饰函数更改连接属性,从外部链接属性改变为内部链接属性
//1.检查数据插入时,是否需要扩容,如果需要,则扩容
static void CheckCapacity(SeqList* seqlist){
	if (seqlist->size < seqlist->capacity){
		//不需要扩容,结束
		return;
	}
	else{
		//需要扩容
		//1.进行扩容
		int newCapacity = 2 * seqlist->capacity;
		SLDataType* newArray = (SLDataType*)malloc(newCapacity * sizeof(SLDataType));
		//2.copy 旧空间的数据到新的空间
		int i = 0;
		for (i = 0; i < seqlist->size; ++i){
			newArray[i] = seqlist->array[i];
		}
		//3.释放旧的空间,并把新的空间绑定到顺序表结构体
		free(seqlist->array);
		seqlist->array = newArray;				//其实这是指针在传地址,即把新空间的首地址放到seqlist->array
		//4.更新容量
		seqlist->capacity = newCapacity;
	}
}
//2.初始化
void SeqListInit(SeqList* seqlist, int capacity){
	//在堆上分配顺序表的存储空间
	//初始化容量和size字段
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	seqlist->array = (SLDataType*)malloc(capacity * sizeof(SLDataType));	//开辟指定长度的空间,并把地址给seqlist->array
	seqlist->capacity = capacity;		//指定容量
	seqlist->size = 0;		//初始长度为0
}
//3.销毁
void SeqListDestory(SeqList* seqlist){
	//在释放顺序表的存储空间
	//额外的工作,把字段重置为初始值
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	free(seqlist->array);		//释放空间
	//锦上添花
	seqlist->array = NULL;		//指向空
	seqlist->capacity =	seqlist->size = 0;		//置零
}
//4.尾插
//时间复杂度为O(1)
void SeqListPushBack(SeqList* seqlist, SLDataType v){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	CheckCapacity(seqlist);			//插入之前要检查空间是否已满(是否需要扩容)
	seqlist->array[seqlist->size] = v;
	++seqlist->size;
}
//5.头插
void SeqListPushFront(SeqList* seqlist, SLDataType v){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	CheckCapacity(seqlist);
	int i = 0;			//用 i 表示下标
	for (i = seqlist->size; i > 0; --i){
		seqlist->array[i] = seqlist->array[i - 1];
	}
	seqlist->array[0] = v;
	++seqlist->size;
}
//6.根据pos下标插入
void SeqListInsert(SeqList* seqlist, int pos, SLDataType v){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	assert(pos >= 0 && pos <= seqlist->size);
	CheckCapacity(seqlist);
	int i = 0;			//用 i 表示下标
	for (i = seqlist->size; i > pos; --i){
		seqlist->array[i] = seqlist->array[i - 1];
	}
	seqlist->array[pos] = v;
	++seqlist->size;
}
//7.尾删
void SeqListPopBack(SeqList* seqlist){
	assert(seqlist != NULL);
	assert(seqlist->size > 0);
	--seqlist->size;
}
//8.头删
void SeqListPopFront(SeqList* seqlist){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	assert(seqlist->size > 0);
	int i = 0;			//用 i 表示下标
	for (i = 0; i <= seqlist->size - 2; ++i){
		seqlist->array[i] = seqlist->array[i + 1];
	}
	--seqlist->size;
}
//9.根据pos下标删除
void SeqListErase(SeqList* seqlist, int pos){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	assert(seqlist->size > 0);
	assert(pos >= 0 && pos < seqlist->size);
	int i = 0;			//用 i 表示下标
	for (i = pos; i <= seqlist->size - 2; ++i){
		seqlist->array[i] = seqlist->array[i + 1];
	}
	--seqlist->size;
}
//10.改
void SeqListModify(SeqList* seqlist, int pos, SLDataType v){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	assert(pos >= 0 && pos < seqlist->size);
	seqlist->array[pos] = v;
}
//11.查
//找到的话返回遇到的第一个 v 的下标,没找到则返回 -1
int SeqListFind(const SeqList* seqlist, SLDataType v){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	for (int i = 0; i < seqlist->size; i++) {
		if (seqlist->array[i] == v) {
			return i;
		}
	}
	return -1;
}
//12.打印
void SeqListPrint(const SeqList* seqlist){
	int i = 0;
	for (i = 0; i < seqlist->size; ++i){
		printf("%d  ",seqlist->array[i]);
	}
	printf("\n");
}
//13.删除第一次遇到的v
void SeqListRemove(SeqList* seqlist, SLDataType v){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	assert(seqlist->size > 0);
	int pos = SeqListFind(seqlist, v);
	if (pos != -1){						//此处需进行判断,如果没有找到则返回-1,-1的话就不需要删除了
		SeqListErase(seqlist, pos);
	}
}
//14.删除遇到的所有的v
void SeqListRemoveAll(SeqList* seqlist, SLDataType v){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	assert(seqlist->size > 0);
	int pos = 0;
	for (pos = 0; pos < seqlist->size; ++pos){
		int pos = SeqListFind(seqlist, v);
		if (pos != -1){
			SeqListErase(seqlist, pos);
		}
	}
}
//15.冒泡排序
void SeqListBubbleSort(SeqList* seqlist){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	int i = 0, j = 0;
	for (i = 0; i < seqlist->size - 1; ++i){
		for (j = i+1; j < seqlist->size; ++j){
			if (seqlist->array[i] > seqlist->array[j]){
				SLDataType tmp;
				tmp = seqlist->array[i];
				seqlist->array[i] = seqlist->array[j];
				seqlist->array[j] = tmp;
			}
		}
	}
}
//16.二分查找
int SeqListBinaryFind(SeqList* seqlist, SLDataType v){
	assert(seqlist != NULL);
	assert(seqlist->array != NULL);
	assert(seqlist->size > 0);
	int left = 0, mid = 0, right = seqlist->size - 1;
	while(left <= right){
		mid = (left + right) / 2;
		if (seqlist->array[mid] == v){
			return mid;
		}
		else if (seqlist->array[mid] > v){
			right = mid - 1;
		}
		else if (seqlist->array[mid] < v){
			left = mid + 1;
		}
	}
	return -1;
}

2.函数声明的 .h 头文件

#pragma once

//静态顺序表:顺序表的容量在编译期间(静态期间)决定的,写死在代码里的
/*
typdef struct SeqList{
	int array[100];		//容量是100
	int size;
}SeqList;
*/

typedef int SLDataType;

//定义顺序表结构体
typedef struct SeqList{
	SLDataType* array;	//定义一个int*指针
	int capacity;		//容量
	int size;
}SeqList;


//1.初始化
//初始化的时候size = 0
//size = -1		//最后一个有效数据的下标
void SeqlistInit(SeqList* seqlist, int capacity);

//2.销毁
void SeqListDestory(SeqList* seqlist);


//1.增
//尾插
void SeqListPushBack(SeqList* seqlist, SLDataType v);
//头插
void SeqListPushFront(SeqList* seqlist, SLDataType v);
//根据pos下标插入
void SeqListInsert(SeqList* seqlist, int pos, SLDataType v);

//2.删
//尾删
void SeqListPopBack(SeqList* seqlist);
//头删
void SeqListPopFront(SeqList* seqlist);
//根据pos下标删除
void SeqListErase(SeqList* seqlist, int pos);

//3.改
//inline 内联函数
/*
static void SeqListModify(SeqList* seqlist, int pos, SLDataType v){
	seqlist->array[pos] = v;
}
*/
void SeqListModify(SeqList* seqlist, int pos, SLDataType v);

//4.查
/*
static int SeqListFind(const SeqList* seqlist, SLDataType v){
	for (int i = 0; i < seqlist->size; i++) {
		if (seqlist->array[i] == v) {
			return i;
		}
	}

	return -1;
}
*/
int SeqListFind(const SeqList* seqlist, SLDataType v);


//1.打印
void SeqListPrint(const SeqList* seqlist);

//1.删除第一次遇到的v
void SeqListRemove(SeqList* seqlist, SLDataType v);
//2.删除遇到的所有的v
void SeqListRemoveAll(SeqList* seqlist, SLDataType v);

//1.冒泡排序
void SeqListBubbleSort(SeqList* seqlist);
//2.二分查找
int SeqListBinaryFind(SeqList* seqlist, SLDataType v);

3.主函数 Main.c 文件

/**************************顺序表**************************/
#include "SequenceList.h"
#include <stdlib.h>

void Test1(){
#if 1
	SeqList seqlist;		//定义一个SeqList类型的顺序表seqlist

	SeqListInit(&seqlist, 10);		//初始化这个顺序表seqlist,给定长度为10
	//尾插
	SeqListPushBack(&seqlist, 1);
	SeqListPushBack(&seqlist, 2);
	SeqListPushBack(&seqlist, 3);
	SeqListPushBack(&seqlist, 4);
	SeqListPushBack(&seqlist, 5);//1 2 3 4 5 
	//头插
	SeqListPushFront(&seqlist, 10);
	SeqListPushFront(&seqlist, 20);
	SeqListPushFront(&seqlist, 30);
	SeqListPushFront(&seqlist, 40);
	SeqListPushFront(&seqlist, 50);//50 40 30 20 10 1 2 3 4 5 
	//已经插满,再插入应该需要扩容
	//根据pos下标插入
	SeqListInsert(&seqlist, 5, 666);//50 40 30 20 10 666 1 2 3 4 5 
	//尾删
	SeqListPopBack(&seqlist);//50 40 30 20 10 666 1 2 3 4 
	//头删
	SeqListPopFront(&seqlist);//40 30 20 10 666 1 2 3 4 
	//根据pos下标删除
	SeqListErase(&seqlist, 2);//40 30 10 666 1 2 3 4 
	//改
	SeqListModify(&seqlist, 6, 2);//40 30 10 666 1 2 2 4 
	//查
	printf("查: %d\n", SeqListFind(&seqlist, 1));//4
	//删除第一遇到的v
	SeqListRemove(&seqlist, 1);//40 30 10 666 2 2 4 
	//删除遇到的所有的v
	SeqListRemoveAll(&seqlist, 2);//40 30 10 666 4 
	//冒泡排序
	SeqListBubbleSort(&seqlist);//4 10 30 40 666
	//二分查找
	printf("二分查: %d\n", SeqListBinaryFind(&seqlist, 4));//3
#endif
	SeqListPrint(&seqlist);
}


int main(){
	Test1();
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值