您的位置:首页 > 编程语言 > C语言/C++

c语言动态顺序表的实现

2017-07-28 12:01 225 查看
动态顺序表是在静态顺序表的基础上优化更改的

1.其中将静态顺序表中的数组数据类型改成了指针类型方便内存的开辟

2.多增加了一个容量的变量来表示顺序表的容量

3.初始化的时候需要给*data动态开辟空间

4.多增加的函数有1.增容函数  2.减容函数  3.空间销毁函数(因为malloc的空间使用完毕后一定要释放内存,不然会造成内存泄露)

动态顺序表的优点:开辟的空间灵活自如,添加元素时自动增容,删除元素时自动减容,节省内存空间。

接下来给出具体实现代码

SeqList.h

:顺序表头文件部分主要存放函数声明和头文件宏定义

#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __SEQLIST_H__
#define __SEQLIST_H__

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

#define DEDAULT_SZ 2   //定义顺序表容量的初始化值
#define INC 1
typedef int DataType;//定义顺序表数据类型

typedef struct SeqList
{
DataType *data;//数据类型
int sz;//元素数量
int capacity;//容量
}SeqList, *pSeqList;

void InitSeqList(pSeqList ps);//初始化顺序表
void destory_mylist(pSeqList ps);//销毁初始化的空间
void checkcapalist(pSeqList ps);//增容函数
void delecapalist(pSeqList ps);//减容函数
void PushBack(pSeqList ps, DataType d);//插尾
void PopBack(pSeqList ps);//删尾
void Display(const pSeqList ps);//打印顺序表
void PushFront(pSeqList ps, DataType d);//插头
void PopFront(pSeqList ps);//删头
int Find(pSeqList ps, DataType d);//查找你要的元素
void Insert(pSeqList ps, DataType d, int pos);//在给定的位置插入元素
void Remove(pSeqList ps, DataType d);//删除你要删除的元素第一个
void RemoveAll(pSeqList ps, DataType d);//删除你要删除的的出现的所有元素
void Reverse(pSeqList ps);//逆序顺序表
void Sort(pSeqList ps);//排序逆序表
int BinarySearch(pSeqList ps, DataType d);//二分查找
#endif //__SEQLIST_H__
SeqList.c

:相关功能函数的具体实现

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void InitSeqList(pSeqList ps)//初始化顺序表,动态开辟内存
{
assert(ps != NULL);
ps->sz = 0;
ps->capacity = DEDAULT_SZ;//容量初始化为2
ps->data = (DataType *)malloc((ps->capacity)*sizeof(DataType));
if(ps->data == NULL)
{
perror("molloc");
exit(EXIT_FAILURE);
}
memset(ps->data, 0, (ps->capacity)*sizeof(DataType));
}
void destory_mylist(pSeqList ps)//free初始化的时候动态开辟的空间
{
assert(ps != NULL);
free(ps->data);
ps->data = NULL;
ps->sz = 0;
ps->capacity = 0;
}
void checkcapalist(pSeqList ps)
{
assert(ps != NULL);
if (ps->sz == ps->capacity)//如果等于容量就满了就增容
{
DataType *ptr = realloc(ps->data, (ps->capacity + INC)*sizeof(DataType));
if (ptr != NULL)
{
ps->data = ptr;
ps->capacity += INC;
}
else
{
perror("realloc");
exit(EXIT_FAILURE);
}
}
}
void PushBack(pSeqList ps, DataType d)//在尾部插入尾函数
{
assert(ps != NULL);
checkcapalist(ps);//进行增容
ps->data[ps->sz] = d;
ps->sz++;
}
void Display(const pSeqList ps)//打印函数
{
int i = 0;
assert(ps != NULL);
for (i = 0; i < ps->sz; i++)
{
printf("%d ", ps->data[i]);
}
printf("\n");
}
void PopBack(pSeqList ps)//删除尾部的元素函数
{
assert(ps != NULL);
ps->sz--;
}
void PushFront(pSeqList ps, DataType d)//从头部开始插入元素
{
assert(ps != NULL);
checkcapalist(ps);//是否需要增容
int i = 0;
for (i = ps->sz; i>0; i--)
{
ps->data[i] = ps->data[i - 1];
}
ps->data[0] = d;
ps->sz++;

}
void delecapalist(pSeqList ps)//减容函数
{
assert(ps != NULL);
if (ps->sz < ps->capacity)
{
DataType *ptr = realloc(ps->data, (ps->capacity - INC)*sizeof(DataType));
if (ptr != NULL)
{
ps->data = ptr;
ps->capacity -= INC;
}
else
{
perror("realloc");
exit(EXIT_FAILURE);
}
}
}
void PopFront(pSeqList ps)//删除头部
{
int i = 0;
assert(ps != NULL);
for (i = 0; i < ps->sz; i++)
{
ps->data[i] = ps->data[i + 1];
}
ps->sz--;
delecapalist(ps);//减容
}
int Find(pSeqList ps, DataType d)//查找第几个元素
{
int i = 0;
if (ps != NULL);
for (i = 0; i < ps->sz; i++)
{
if (ps->data[i] == ps->data[d - 1])
return ps->data[i];
}
return -1;
}
void Insert(pSeqList ps, DataType d, int pos)//指定位置插入元素,d要插入的元素,pos指定位置
{
assert(ps != NULL);
checkcapalist(ps);//增容
int i = 0;
for (i = ps->sz; i>pos - 1; i--)
{
ps->data[i] = ps->data[i - 1];
}
ps->data[pos - 1] = d;
ps->sz++;

}
void Remove(pSeqList ps, DataType d)//删除你要删除的第一个出现的元素
{
int i = 0, j = 0;;
assert(ps != NULL);
for (i = 0; i < ps->sz; i++)
{

if (ps->data[i] == d)
{
for (j = i; j < ps->sz; j++)
{
ps->data[j] = ps->data[j + 1];
}
ps->sz--;
delecapalist(ps);//减容
break;
}
}
}
void RemoveAll(pSeqList ps, DataType d)//删除你要删除的所有元素
{
int i = 0, j = 0;;
assert(ps != NULL);
for (i = 0; i < ps->sz; i++)
{
if (ps->data[i] == d)
{
for (j = i; j < ps->sz; j++)
{
ps->data[j] = ps->data[j + 1];
}
ps->sz--;
delecapalist(ps);//减容
i = 0;
}
}
}
void Reverse(pSeqList ps)//逆序顺序表
{
assert(ps != NULL);
int i = 0, j = ps->sz - 1;
int n = ps->sz / 2;
for (i = 0; i <= n / 2; i++, j--)
{
int temp = 0;
temp = ps->data[i];
ps->data[i] = ps->data[j];
ps->data[j] = temp;
}
}
void Sort(pSeqList ps)//排序,采用的是冒泡排序
{
assert(ps != NULL);
int i = 0, j = 0;
for (i = 0; i < ps->sz - 1; i++)
{
for (j = 0; j < ps->sz - 1 - i; j++)
{
int temp = 0;
if (ps->data[j]>ps->data[j + 1])
{
temp = ps->data[j];
ps->data[j] = ps->data[j + 1];
ps->data[j + 1] = temp;
}
}
}
}
int BinarySearch(pSeqList ps, DataType d)//二分查找,d表示你要查找的元素
{
int left = 0;
int right = ps->sz - 1;
while (left < right)
{
int mid = (right - left) / 2 + left;
if (d>ps->data[mid])
{
left = mid + 1;
}
else if (d < ps->data[mid])
{
right = mid - 1;
}
else
{
return mid;
}
}
}
test.c

主函数部分和测试函数

#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void test()
{
SeqList my_list;//创建结构提变量
InitSeqList(&my_list);//初始化函数
PushBack(&my_list, 1);//插尾函数
PushBack(&my_list, 2);//插尾函数
PushBack(&my_list, 3);//插尾函数
PushBack(&my_list, 2);//插尾函数
PushBack(&my_list, 3);//插尾函数
PushBack(&my_list, 4);//插尾函数
Display(&my_list);//打印数序表
//PopFront(&my_list);//删除头部
//Display(&my_list);//打印数序表
////PopBack(&my_list);//删除尾部元素的信息
////Display(&my_list);//打印数序表
//PushFront(&my_list, 1);//从头部插入
//PushFront(&my_list, 2);
//PushFront(&my_list, 3);
//PushFront(&my_list, 4);
//Display(&my_list);
///*Insert(&my_list, 10, 4
4000
);*///指定位置插入元素
/*Remove(&my_list, 2);*///删除所有你想删除的元素出现的第一个
RemoveAll(&my_list, 2);//删除顺序表中出现的所有你要删除的元素
Display(&my_list);//打印数序表
destory_mylist(&my_list);//
////Display(&my_list);
///*Reverse(&my_list);*///逆序的测试
//Sort(&my_list);//排序的测试
//Display(&my_list);
//int ret = BinarySearch(&my_list, 1);//二分查找的测试
//printf("%d", ret);
///*destory_mylist(&my_list);*/
}
int main()
{
test();//测试函数,用来测试顺序表所有功能
system("pause");
return 0;
}
我的测试函数里面的内容是根据我在编写的时候的实际情况测试的,你可以根据自己的想法重新编排测试函数的顺序达到你要的测试效果

注意:一定记得使用完malloc开辟的内存空间以后调用销毁空函数destory_mylist(&my_list)进行内存释放!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息