顺序表的操作功能大全

       我们对此分为三个文件,两个源文件SeqList.c  main.c 和一个头文件SeqList.h。

       SeqList.h 中用来包含头文件,定义结构体,和对函数的声明;SeqList.c 中写对函数的实现; main.c 中是主函数和测试函数。

       "SeqList.h"

 

#pragma once

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>
#include<assert.h>

typedef int SLDataType;

typedef struct SeqList{
	SLDataType *array;
	int capacity;  //最大容量
	int size;      //实际存储容量
}SeqList;


// 初始化
void SeqListInit(SeqList *sl, size_t capacity);

//销毁
void SeqListDestroy(SeqList *sl);

//打印
void SeqListPrint(SeqList *sl);

//检查是否已满,若满则扩容
void CheckCapacity(SeqList *sl);

// 尾插,插入在顺序表的尾部
void SeqListPushBack(SeqList *sl, SLDataType data);

// 头插,插入在顺序表的头部 ([0])
void SeqListPushFront(SeqList *sl, SLDataType data);

// 尾删,删除顺序表尾部的数据
void SeqListPopBack(SeqList *sl);

// 头删,删除顺序表头部的数据
void SeqListPopFront(SeqList *sl);

// 在 pos 所在的下标做数据插入
void SeqListInsert(SeqList *sl, size_t pos, SLDataType data);

// 查找
// 找从 0 开始的第一个
//如果找到了,返回数据所在的下标;如果没找到返回 -1
int SeqListFind(SeqList *sl, SLDataType data);

// 删除 pos 所在的下标数据
void SeqListErase(SeqList *sl, size_t pos);

// 删除第一个遇到的 data
void SeqListRemove(SeqList *sl, SLDataType data);

// 删除所有遇到的 data
void SeqListRemoveAll(SeqList *sl, SLDataType data);

// 修改,pos 所在的下标
void SeqListModify(SeqList *sl, size_t pos, SLDataType data);

//交换
void Swap(a, b);

//冒泡查找
void SeqListBubbleSort(SeqList *sl);

//二分查找(顺序排列情况下)
int SeqListBinarySearch(SeqList *sl, SLDataType data);

 "SeqList.c"

#include"SeqList.h"

void SeqListInit(SeqList *sl, size_t capacity)
{
	sl->capacity = capacity;
	sl->size = 0;
	sl->array = (SLDataType *)malloc(capacity * sizeof(SLDataType));
	assert(sl->array != NULL);
}

void SeqListDestroy(SeqList *sl)
{
	assert(sl != NULL);
	//推荐后初始化的先销毁
	free(sl->array);
	sl->array = NULL;//防御性代码
	sl->size = 0;
	sl->capacity = 0;
}

void SeqListPrint(SeqList *sl)
{
	for (int i = 0; i < sl->size; i++)
	{
		printf("%d  ", sl->array[i]);
	}
	printf("\n");
}

void CheckCapacity(SeqList *sl)
{
	assert(sl != NULL);
	//未满,不需扩容
	if (sl->size < sl->capacity)
	{
		return;
	}
	//满,扩容
	//1.申请新空间
	int newCapacity = sl->capacity * 2;
	SLDataType *newArray = 
		(SLDataType *)malloc(newCapacity * sizeof(SLDataType));
	assert(newArray);
	//2.数据搬移至新空间
	for (int i = 0; i < sl->size; i++)
	{
		newArray[i] = sl->array[i];
	}
	//3.释放旧的空间(防止内存泄漏)
	free(sl->array);        
	//4.保存新的空间
	sl->array = newArray;
	sl->capacity = newCapacity;
}

void SeqListPushBack(SeqList *sl, SLDataType data)
{
	assert(sl != NULL);
	CheckCapacity(sl);

	sl->array[sl->size] = data;
	sl->size++;
}

void SeqListPushFront(SeqList *sl, SLDataType data)
{
	assert(sl != NULL);
	CheckCapacity(sl);
	//从最后一位开始依次向后挪 下标i size-1 ~ 0
	for (int i = sl->size - 1; i >= 0; i--)
	{
		sl->array[i + 1] = sl->array[i];
	}
	sl->array[0] = data;
	sl->size++;
}

void SeqListPopBack(SeqList *sl)
{
	assert(sl != NULL);
	assert(sl->size > 0);
	sl->size--;
}

void SeqListPopFront(SeqList *sl)
{
	assert(sl != NULL);
	assert(sl->size > 0);

	for (int i = 1; i <= sl->size - 1; i++)
	{
		sl->array[i - 1] = sl->array[i];
	}
	sl->size--;
}

void SeqListInsert(SeqList *sl, size_t pos, SLDataType data)
{
	assert(sl != NULL);
	CheckCapacity(sl);
	//下标 pos 有效范围 [0, size] ,当为size时,即直接尾插
	assert((int)pos >= 0 && (int)pos <= sl->size);
	// i 表示下标,从后往前开始移动 size-1 ~ pos
	for (int i = sl->size - 1; i >= (int)pos; i--)
	{
		sl->array[i + 1] = sl->array[i];
	}
	sl->array[pos] = data;
	sl->size++;
}

int SeqListFind(SeqList *sl, SLDataType data)
{
	assert(sl != NULL);
	for (int i = 0; i < sl->size; i++)
	{
		if (sl->array[i] == data)
		{
			return i;
		}
	}
	return -1;
}

void SeqListErase(SeqList *sl, size_t pos)
{
	assert(sl != NULL);
	//必须有数据才能删
	assert(sl->size > 0);

	//下标范围 [0, size-1]
	assert((int)pos >= 0 && (int)pos < sl->size);

	// i 表示数据下标  pos+1 ~ size-1
	for (int i = pos + 1; i <= sl->size - 1; i++)
	{
		sl->array[i - 1] = sl->array[i];
	}
	sl->size--;
}

void SeqListRemove(SeqList *sl, SLDataType data)
{
	int pos = SeqListFind(sl, data);
	if (pos != -1)
	{
		SeqListErase(sl, pos);
	}
}

void SeqListRemoveAll(SeqList *sl, SLDataType data)
{
#if 0	// 时间复杂度 O(n^2)
	int pos;
	while ((pos = SeqListFind(sl, data)) != -1) {	// O(n)
		SeqListErase(sl, pos);	// O(n)
	}
#endif

#if 0	// 时间复杂度 O(n),空间复杂度 O(n)
	SLDataType *tempArray = (SLDataType *)malloc(
		sizeof(SLDataType)* sl->size);
	assert(tempArray);
	int j = 0;

	for (int i = 0; i < sl->size; i++) {
		if (sl->array[i] != data) {
			tempArray[j++] = sl->array[i];
		}
	}

	for (int k = 0; k < j; k++) {
		sl->array[k] = tempArray[k];
	}

	sl->size = j;
#endif

	// i 控制原数据的下标移动,进行遍历
	// j 控制新数据的下标移动,不删除则开始新的排序
	int j = 0;
	for (int i = 0; i < sl->size; i++)
	{
		if (sl->array[i] != data)
		{
			sl->array[j++] = sl->array[i];
		}
	}
	sl->size = j;
}

void SeqListModify(SeqList *sl, size_t pos, SLDataType data)
{
	assert(sl);
	assert((int)pos >= 0 && (int)pos < sl->size);

	sl->array[pos] = data;
}

void Swap(int *a, int *b)
{
	int t = *a;
	*a = *b;
	*b = t;
}

void SeqListBubbleSort(SeqList *sl)
{
	assert(sl != NULL);
	for (int i = 0; i < sl->size - 1; i++)
	{
		int flag = 1;
		for (int j = 0; j < sl->size - 1 - i; j++)
		{
			if (sl->array[j] > sl->array[j + 1])
			{
				Swap(&sl->array[j], &sl->array[j + 1]);
				flag = 0;
			}
		}
		if (flag)
		{
			return;
		}
	}
}

int SeqListBinarySearch(SeqList *sl, SLDataType data)
{
	assert(sl != NULL);
	int left = 0;
	int right = sl->size - 1;
	while (left <= right)
	{
		int mid = left + (right - left) / 2;
		if (sl->array[mid] < data)
		{
			left = mid + 1;
		}
		else if (sl->array[mid] > data)
		{
			right = mid - 1;
		}
		else
		{
			return mid;
		}
	}
	return -1;//没找到
}


      "main.c"

#include"SeqList.h"

void test()
{
	SeqList sl;
	SeqListInit(&sl, 3);

	SeqListInsert(&sl, 0, 3);
	SeqListInsert(&sl, 1, 4);
	SeqListInsert(&sl, 2, 5);
	SeqListInsert(&sl, 1, 6);
	SeqListInsert(&sl, 1, 7);
	SeqListInsert(&sl, 0, 3);
	SeqListInsert(&sl, 1, 4);
	SeqListInsert(&sl, 2, 5);

	SeqListPrint(&sl);

	SeqListErase(&sl, 1);
	SeqListPrint(&sl);

	SeqListRemove(&sl, 7);
	SeqListPrint(&sl);
	SeqListRemoveAll(&sl, 5);
	SeqListPrint(&sl);

	SeqListModify(&sl, 0, 11);
	SeqListPrint(&sl);

	SeqListPushBack(&sl, 20);
	SeqListPrint(&sl);

	SeqListPushFront(&sl, 10);
	SeqListPrint(&sl);

	SeqListPopBack(&sl);
	SeqListPrint(&sl);

	SeqListPopFront(&sl);
	SeqListPrint(&sl);

	SeqListBubbleSort(&sl);
	SeqListPrint(&sl);

	
	printf("%d\n", SeqListBinarySearch(&sl, 2));
	printf("%d\n", SeqListBinarySearch(&sl, 3));
	printf("%d\n", SeqListBinarySearch(&sl, 6));
	printf("%d\n", SeqListBinarySearch(&sl, 11));
}

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

        以上便是我写的对顺序表功能的实现,其中的main.c 文件中的 test 函数是我自己在实现过程中的测试,可以有自己的测试方法,不一定按部就班,只要能对函数功能进行检测即可。

        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值