C语言 顺序表的实现 (动态)

上一篇博客写了顺序表的静态实现,即指定大小的顺序表,这篇则给出动态实现的顺序表,即可以改变大小的顺序表。

给出顺序表的定义:

typedef int DataType;
typedef struct SeqListD {
	DataType *array;
	int size;// 记录有效元素的个数
	int capacity;// 空间总大小
}SeqListD, *PSeqListD;

将函数的声明放在head.h的头文件里面:

#ifndef _HEAD_H_
#define _HEAD_H_

#define INIT_SIZE 10
#define INCREMENT 5
typedef int DataType;
typedef struct SeqListD {
	DataType *array;
	int size;// 记录有效元素的个数
	int capacity;// 空间总大小
}SeqListD, *PSeqListD;

void CheckCapacity(PSeqListD pSeqList);//检查当前线性表的容量,不够的话申请内存
void InitSeqList(PSeqListD pSeqList);//线性表初始化
void PushBack(PSeqListD pSeqList, DataType data);//在线性表后面插入元素
void PopBack(PSeqListD pSeqList);//在线性表后面删除元素
void PushFront(PSeqListD pSeqList, DataType data);//在线性表前面插入元素
void PopFront(PSeqListD pSeqList);//在线性表前面删除元素
void Insert(PSeqListD pSeqList, int pos, DataType data);//在线性表指定位置插入元素
void Erase(PSeqListD pSeqList, int pos);//在线性表指定位置删除元素
int Find(PSeqListD pSeqList, DataType data);//在线性表查找元素,返回下标
void Remove(PSeqListD pSeqList, DataType data);//在线性表删除值为data的元素
void RemoveAll(PSeqListD pSeqList, DataType data);//在线性表删除所有值为data的元素
int Empty(PSeqListD pSeqList);//判别线性表是否为空
void PrintSeqList(PSeqListD pSeqList);//打印线性表
void BubbleSort(PSeqListD pSeqList, int(*cmp)(const void *elem1, const void *elem2));//冒泡排序,升序和降序两种版本,用了函数指针以及回调函数
void SelectSort(PSeqListD pSeqList, int(*cmp)(const void *elem1, const void *elem2));//选择排序,升序和降序两种版本,用了函数指针以及回调函数
int CmpInAscendingOrder(const void *elem1, const void *elem2);//升序比较
int CmpInDescendingOrder(const void *elem1, const void *elem2);//降序比较
void swap(DataType *a, DataType *b);//交换
int BinarySearch(PSeqListD pSeqList, DataType data);//二分查找
int BinarySearchRecursion(PSeqListD pSeqList, int left, int right, DataType data);//二分查找的递归版本
int Size(PSeqListD pSeqList);//求线性表的大小
void Clear(PSeqListD pSeqList);//清空线性表
void DestroySeqList(PSeqListD pSeqList);//销毁线性表

#endif 

具体的实现

test()函数为测试代码,只写出了其中的一部分

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

void test0();
void test1();
void test2();
void test3();

int main()
{
	//test0();
	//test1();
	//test2();
	test3();
	getchar();
	return 0;
}

void test0()
{
	SeqListD seqlist;
	PSeqListD p = &seqlist;
	InitSeqList(p);
	PushBack(p, 1);
	PushBack(p, 2);
	PushBack(p, 3);
	PrintSeqList(p);
	PopBack(p);
	PopBack(p);
	PrintSeqList(p);

}

void test1()
{
	SeqListD seqlist;
	PSeqListD p = &seqlist;
	InitSeqList(p);
	PushBack(p, 1);
	PushBack(p, 2);
	PushBack(p, 3);
	PushBack(p, 5);
	PrintSeqList(p);
	Insert(p, 4, 4);
	Erase(p, 1);
	PrintSeqList(p);
}

void test2()
{
	SeqListD seqlist;
	PSeqListD p = &seqlist;
	InitSeqList(p);
	PushBack(p, 1);
	PushBack(p, 6);
	PushBack(p, 3);
	PushBack(p, 4);
	PushBack(p, 2);
	PushBack(p, 5);
	PrintSeqList(p);
	//BubbleSort(p, CmpInAscendingOrder);
	//SelectSort(p, CmpInAscendingOrder);
	PrintSeqList(p);
	//BubbleSort(p, CmpInDescendingOrder);
	//SelectSort(p, CmpInDescendingOrder);

	//int pos = BinarySearch(p, 20) + 1;
	//printf("%d\n", pos);
}

void test3()
{
	SeqListD seqlist;
	PSeqListD p = &seqlist;
	InitSeqList(p);
	PushBack(p, 1);
	PushBack(p, 2);
	PushBack(p, 3);
	PushBack(p, 5);
	PushBack(p, 2);
	PushBack(p, 2);
	PushBack(p, 4);
	PrintSeqList(p);
	RemoveAll(p, 2);
	PrintSeqList(p);

}

void CheckCapacity(PSeqListD pSeqList)
{
	assert(pSeqList);
	if (pSeqList->size >= pSeqList->capacity) {
		DataType *p = (DataType *)realloc(pSeqList->array, (INIT_SIZE + INCREMENT) * sizeof(DataType));
		if (!p)
			exit(EXIT_FAILURE);
		pSeqList->array = p;
		pSeqList->capacity += INCREMENT;
	}
}

void InitSeqList(PSeqListD pSeqList)
{
	assert(pSeqList);
	pSeqList->array = (DataType *)malloc(INIT_SIZE * sizeof(DataType));
	if (!(pSeqList->array)) {
		exit(EXIT_FAILURE);
	}
	pSeqList->size = 0;
	pSeqList->capacity = INIT_SIZE;
}

void PushBack(PSeqListD pSeqList, DataType data)
{
	assert(pSeqList);
	CheckCapacity(pSeqList);
	pSeqList->array[pSeqList->size++] = data;
}

void PopBack(PSeqListD pSeqList)
{
	assert(pSeqList);
	pSeqList->size--;
}

void PushFront(PSeqListD pSeqList, DataType data)
{
	assert(pSeqList);
	CheckCapacity(pSeqList);
	for (int i = pSeqList->size; i > 0; --i) {
		pSeqList[i] = pSeqList[i - 1];
	}
	pSeqList->array[0] = data;
	pSeqList->size++;
}

void PopFront(PSeqListD pSeqList)
{
	assert(pSeqList);
	pSeqList->size--;
	for (int i = 0; i < pSeqList->size; i++) {
		pSeqList->array[i] = pSeqList->array[i + 1];
	}
}

void PrintSeqList(PSeqListD pSeqList)
{
	assert(pSeqList);
	printf("the elements in the seqlist:");
	for (int i = 0; i < pSeqList->size; ++i) {
		printf("%d ", pSeqList->array[i]);
	}
	printf("\n");
}

void Insert(PSeqListD pSeqList, int pos, DataType data)
{
	assert(pSeqList);
	CheckCapacity(pSeqList);
	if (1 <= pos <= pSeqList->size) {
		int truePos = pos - 1;
		for (int i = pSeqList->size; i > truePos; --i) {
			pSeqList->array[i] = pSeqList->array[i - 1];
		}
		pSeqList->array[truePos] = data;
		pSeqList->size++;
	}
	else {
		printf("the pos is wrong\n");
	}
}

void Erase(PSeqListD pSeqList, int pos)
{
	assert(pSeqList);
	if (1 <= pos && pos <= pSeqList->size) {
		int truePos = pos - 1;
		pSeqList->size--;
		for (int i = truePos; i < pSeqList->size; ++i) {
			pSeqList->array[i] = pSeqList->array[i + 1];
		}
	}
	else {
		printf("the pos is wrong\n");
	}
}

int Find(PSeqListD pSeqList, DataType data)
{
	assert(pSeqList);
	for (int i = 0; i < pSeqList->size; ++i) {
		if (pSeqList->array[i] == data)
			return i + 1;
	}
	return 0;
}

void Remove(PSeqListD pSeqList, DataType data)
{
	assert(pSeqList);
	int pos = Find(pSeqList, data);
	if (pos != 0) {
		Erase(pSeqList, pos);
	}
}

void RemoveAll(PSeqListD pSeqList, DataType data)
{
	assert(pSeqList);
	int count = 0;
	for (int i = 0; i < pSeqList->size; ++i) {
		if (pSeqList->array[i] == data)
			count++;
		else
			pSeqList->array[i - count] = pSeqList->array[i];
	}
	pSeqList->size -= count;
	//while (count--) {
	//	Remove(pSeqList, data);
	//}

}


int Empty(PSeqListD pSeqList)
{
	return pSeqList->size == 0;
}

void swap(DataType *a, DataType *b)
{
	DataType tmp = *a;
	*a = *b;
	*b = tmp;
}

int CmpInAscendingOrder(const void *elem1, const void *elem2)
{
	return *(int *)elem1 - *(int *)elem2;
}

int CmpInDescendingOrder(const void *elem1, const void *elem2)
{
	return *(int *)elem2 - *(int *)elem1;
}

void BubbleSort(PSeqListD pSeqList, int(*cmp)(const void *elem1, const void *elem2))
{
	assert(pSeqList);
	int i = 0; 
	int j = 0;
	for (i = 0; i < pSeqList->size - 1; ++i) {
		for (j = 0; j < pSeqList->size - 1 - i; ++j) {
			if (cmp(&pSeqList->array[j], &pSeqList->array[j + 1]) > 0)
				swap(&pSeqList->array[j], &pSeqList->array[j + 1]);
		}
	}
}

void SelectSort(PSeqListD pSeqList, int(*cmp)(const void *elem1, const void *elem2))
{
	assert(pSeqList);
	int pos = 0;
	int i = 0; 
	int j = 0;
	for (i = 0; i < pSeqList->size - 1; ++i) {
		pos = i;
		for (j = i + 1; j < pSeqList->size; ++j) {
			if (cmp(&pSeqList->array[j], &pSeqList->array[pos]) > 0) {
				pos = j;
			}
		}
		if (pos != i) {
			swap(&pSeqList->array[i], &pSeqList->array[pos]);
		}
	}
}

int BinarySearch(PSeqListD pSeqList, DataType data)
{
	int left = 0;
	int right = pSeqList->size - 1;
	while (left <= right) {
		int mid = left + ((right - left) >> 1);
		if (pSeqList->array[mid] < data)
			left = mid + 1;
		else if (pSeqList->array[mid] > data)
			right = mid - 1;
		else
			return mid;
	}
	return -1;
}

int BinarySearchRecursion(PSeqListD pSeqList, int left, int right, DataType data)
{
	if (left <= right) {
		int mid = left + (right - left) / 2;
		if (data > pSeqList->array[mid])
			return BinarySearchRecursion(pSeqList, mid + 1, right, data);
		else if (data < pSeqList->array[mid])
			return BinarySearchRecursion(pSeqList, left, mid - 1, data);
		else
			return mid;
	}
	else
		return -1;
}

int Size(PSeqListD pSeqList)
{
	return pSeqList->size;
}

void Clear(PSeqListD pSeqList)
{
	for (int i = 0; i < pSeqList->size; ++i) {
		pSeqList->array[i] = 0;
	}
}

void DestroySeqList(PSeqListD pSeqList)
{
	free(pSeqList->array);
	pSeqList->capacity = 0;
	pSeqList->size = 0;
}



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值