动态顺序表的实现

在这里插入图片描述
与静态顺序表相比,动态顺序表更具需要动态的分配空间大小,
从而解决了静态顺序表的定长所带来的系列问题.

函数声明
#ifndef _SEQLIST_H
#define _SEQLIST_H

#include<stdio.h>
#include<windows.h>
#include<assert.h>
#pragma warning (disable:4996)
#define LIST_SIZE 100
#define ADD_SIZE  20
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType *array;
	int capacity;
	int size;
}SeqList, *pSeqList;



void SeqListInit(pSeqList psl);//初始化
void SeqListDestory(pSeqList sql);// 销毁
void checkCapacity(pSeqList psl); // 顺序表的扩容
void SeqListPushFront(pSeqList psl, SLDataType data); //头插
void SeqListPushBack(pSeqList psl, SLDataType Data);//尾插
void SeqListPopBack(pSeqList psl); // 头删
void SeqListPopBack(pSeqList psl); // 尾删
int SeqListFind(pSeqList sql, SLDataType x); // 查找
void SeqListInsert(pSeqList psl, int pos, SLDataType data);// 向pos位置插入data
void SeqListErase(SeqList*psl, int pos); // 删除pos位置上的元素 
void SeqListRemove(pSeqList psl, SLDataType data); // 删除顺序表值为data的节点
void SeqListModify(pSeqList psl, int pos, SLDataType data);  // 修改pos位置上数据为data
void SeqListPrint(pSeqList psl);  // 打印顺序表
void SeqListBubbleSort(pSeqList psl); // 顺序表冒泡排序
int SeqListBinaryFind(pSeqList psl, SLDataType data); // 二分查找

#endif
函数实现
#include"SeqList.h"


// 初始化
void SeqListInit(pSeqList psl)
{
	assert(psl);  // psl != NULL 继续执行 
	psl->array = (SLDataType*)malloc(sizeof(SLDataType)*LIST_SIZE);
		
		if (NULL == psl->array)  // 内存声请失败
		{
			printf("申请内存空间失败!\n");
			return -1;
		}
		psl->size = 0;
		psl->capacity = LIST_SIZE;

}


// 销毁
void SeqListDestory(pSeqList sql)
{
	assert(sql);
	sql->capacity = 0;
	sql->size = 0;
	free(sql->array);// 一旦我们使用完毕堆上内存一定要归还给操作系统,否则会出现内存泄漏的问题
	sql->array = NULL;    //free掉这段空间之后arr变成了一个野指针,为此我们最好避免
}

//对顺序表进行扩容
void checkCapacity(pSeqList psl)
{
	assert(psl); //判空
	if (psl->size < psl->array)
	{
		return 0;
	}

	//当空间不足时我们就将空间扩充增加 ADD_SIZE 
	SLDataType *newPsl = (SLDataType*)malloc(sizeof(SLDataType)*(psl->capacity + ADD_SIZE));
	assert(newPsl); // 判断申请空间是否为空
	//当新的大空间申请成功之后就需要将原来的数据都搬移到新空间中
	int  i = 0;
	for (i; i < psl->size; i++) 
	{
		newPsl[i] = psl->array[i];
	}

	// 原来psl->array指向的空间已经无用,需要通过手动释放还给空间。
	free(psl->array);

	//重新让psl->arry 指向 新开辟的空间
	psl->array = newPsl; 
}

 //尾插
void SeqListPushBack(pSeqList psl, SLDataType data)
{
	assert(psl);
	checkCapacity;  // 判断空间是否足够,不够进行扩容,足够直接返回

	psl->array[psl->size] = data;
	psl->size++;

}

// 头插
void SeqListPushFront(pSeqList psl,SLDataType data)
{
	assert(psl);
	checkCapacity(psl);  // 判断空间是否足够,不够进行扩容,足够直接返回
	int i = psl->size;
	for (i; i > 0;i--)
	{
		psl->array[i] = psl->array[i- 1];// 从后往前,每个数挪一位
	}

	psl->array[i] = data;
	psl->size++;
}

// 尾删
void SeqListPopBack(pSeqList psl )  
{
	assert(psl);
	if (0 == psl->size) // 如果有效数据为0,则直接退出
	{
		return -1;
	}
	psl->size--;

}

// 头删
void SeqListPopFront(pSeqList psl)
{
	assert(psl);
	if (0 == psl->size) // 如果有效数据为0,则直接退出
	{
		return -1;
	}
	int i = 0;
	for (i; i <psl->size-1; i++) 
	{
		psl->array[i] = psl->array[i+1];// 从前往后,每个数挪一位
	}
	
	psl->size--;
}

void SeqListInsert(pSeqList psl, int pos, SLDataType data)// 向pos位置插入data
{
	assert(psl);
	if (pos >= 0 && pos <psl->size){

		int i = psl->size;
			for (i; i > pos;i--)
			{
				psl->array[i] = psl->array[i - 1];
			}

		psl->array[i] = data;
		psl->size++;

	}
	else
	{
		printf("插入错误!!\n");
	}
	
}

// 查找
int SeqListFind(pSeqList psl, SLDataType data)
{
	assert(psl);
	int i = 0;
	for (i; i < psl->size; i++)
	{
		if (psl->array[i] == data)
		{
			return i;
		}
	}
	
	return -1;

}


void SeqListErase(SeqList*psl, int pos) // 删除pos位置上的元素
{
	assert(psl);
	if (pos >= 0 && pos <psl->size){

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

		psl->size--;

	}
	else
	{
		printf("删除位置错误!!\n");
	}


}

// 移除表中数据为data的元素
void SeqListRemove(pSeqList psl , SLDataType data)
{
	assert(psl);
	int i = 0;
	int count = 0;
	int flag = 0;
	for (i; i < psl->size; i++)
	{
		if (psl->array[i] == data)
		{
			count++;
			flag = 1;
		}
		else
		{
			psl->array[i - count] = psl->array[i];  // 用后面不相同的元素替换掉与data相同的元素
		}

	}

	if (0 == flag)
	{
		printf("该元素不存在\n");
	}
	psl->size -= count;  // 减去被移除的元素
}


void SeqListModify(pSeqList psl, int pos, SLDataType data)  // 修改
{
	assert(psl);
	if (pos >= 0 && pos <psl->size){

		psl->array[pos] = data;

	}
	else
	{
		printf("修改位置错误!!\n");
	}

}
 
void SeqListPrint(pSeqList psl)  // 打印顺序表
{ 
	assert(psl);
	int i = 0;
	for (i; i < psl->size;i++)
	{
		printf("->%d", psl->array[i]);
	}

	printf("\n");
}


void SeqListBubbleSort(pSeqList psl) // 顺序表冒泡排序
{
	assert(psl);
	int i = 0;
	int j = 0;
	for (i; i < psl->size - 1;i++)
	{
		for (j; j < psl->size - 1 - i;j++)
		{
			if (psl->array[j]>psl->array[j + 1])
			{
			
				psl->array[j] ^= psl->array[j + 1];
				psl->array[j+ 1] ^= psl->array[j ];
				psl->array[j] ^= psl->array[j + 1];
			}
				

		}


	}

}



int SeqListBinaryFind(pSeqList psl, SLDataType data)// 二分查找
{
	assert(psl);
	SLDataType left = 0;
	SLDataType right = psl->size-1;
	SLDataType mid = 0;
	while (left <= right)
	{
		mid = (right + left)/2;

		if (data == psl->array[mid])
		{
			return mid;

		}
		else if (data > psl->array[mid])
		{
			 left = mid + 1;

		}
		else
		{
			right = mid - 1;
		}

	}

	return -1;

}
对函数的调用与测试
#include"SeqList.h"
int main()
{
	SeqList s;
	SeqListInit(&s);
	SeqListPushFront(&s, 5);
	SeqListPushFront(&s, 4);
	SeqListPushFront(&s, 3);
	SeqListPushBack(&s, 6);
	SeqListPushBack(&s, 7);
	SeqListPushBack(&s, 8);
	SeqListPushFront(&s, 2);
	SeqListPrint(&s);

	SeqListPopBack(&s);
	SeqListPrint(&s);
	SeqListPopBack(&s);
	SeqListPrint(&s);
	SeqListPopBack(&s);
	SeqListPrint(&s);
	int ret = SeqListFind(&s, 5);
	if (ret != -1)
	{
		printf("该数在 %d 节点\n", ret);
	}
	else
	{

		printf("该数不存在!!\n");
	}
	
	SeqListInsert(&s, 3,10); 
	SeqListPrint(&s);
	SeqListErase(&s, 0);
	SeqListPrint(&s);

	SeqListModify(&s, 3, 8);
	SeqListPrint(&s);
	SeqListModify(&s, 8, 7);


	SeqListBubbleSort(&s);
	SeqListPrint(&s);

	int ret2 = SeqListBinaryFind(&s, 3);

	if (ret2 != -1)
	{
		printf("该数在 %d 节点\n", ret2);
	}
	else
	{

		printf("该数不存在!!\n");
	}

	system("pause"); 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值