前边已经实现了静态顺序表,现在来实现一下动态的。其实动态的就只是将静态定义的数组改为动态开辟一块内存来存放一组数据。
具体代码
头文件及函数声明(SeqList.h)部分
#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define MAX 3//数组元素个数
#define INC 2
typedef int DataType;//数组元素类型重命名
typedef struct SeqList
{
DataType* data;//创建一个数组
int capacity;
int sz; //用于记住元素的个数
}SeqList, *pSeqList;
void InitSeqlist(pSeqList ps);//初始化函数
void PushBack(pSeqList ps, DataType x);//从后边添加的函数
void PrintSeqlist(pSeqList ps);//打印数组的函数
void PopBack(pSeqList ps);//从后往前删除的函数
void PushFront(pSeqList ps, DataType x);//从前边添加的函数
void PopFront(pSeqList ps);//从前往后删除的函数
void Insert(pSeqList ps, int pos, DataType x);//指定位置添加的函数
int Find(pSeqList ps, DataType x);//查找函数
void Remove(pSeqList ps, DataType x); //删除指定某个数的函数
void RemoveAll(pSeqList ps, DataType x);//删除所有的指定的某个值的函数
void ReverseList(pSeqList ps);//逆序函数
void SortList(pSeqList ps);//排序函数
int BinarySearch(pSeqList ps, DataType x);//二分查找函数
void Distroy(pSeqList ps);//销毁并释放动态开辟的内存
#endif
每一个函数的具体实现(SeqList.c)部分
#include "SeqList.h"
void InitSeqlist(pSeqList ps)
{
//memset(ps->data, 0, MAX*sizeof(DataType));
ps->data = (DataType *)malloc(MAX*sizeof(DataType));
if (ps->data == NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}
memset(ps->data, 0, MAX*sizeof(DataType));
ps->sz = 0;
ps->capacity = MAX;
}
//检查是否需要增容,若需要则增容
void Check(pSeqList ps)
{
assert(ps != NULL);
if (ps->sz == ps->capacity)
{
DataType* tmp = (DataType *)realloc(ps->data, (ps->capacity + INC)*sizeof(DataType));
if (tmp == NULL)
{
perror("realloc");
exit(EXIT_FAILURE);
}
ps->data = tmp;
ps->capacity += INC;
}
}
//后加
void PushBack(pSeqList ps, DataType x)
{
assert(ps != NULL);
Check(ps);
ps->data[ps->sz] = x;
ps->sz++;
}
//打印
void PrintSeqlist(pSeqList ps)
{
assert(ps != NULL);
int i = 0;
if (ps->sz == 0)
{
return;
}
for (i = 0; i < ps->sz; i++)
{
printf("%d ", ps->data[i]);
}
printf("\n");
}
//后删
void PopBack(pSeqList ps)
{
assert(ps != NULL);
if (ps->sz == 0)
{
return;
}
ps->sz--;
}
//前加
void PushFront(pSeqList ps, DataType x)
{
assert(ps != NULL);
Check(ps);
memmove(ps->data + 1, ps->data, (ps->sz)*sizeof(DataType));
ps->data[0] = x;
ps->sz++;
}
//前删
void PopFront(pSeqList ps)
{
assert(ps != NULL);
if (ps->sz == 0)
{
return;
}
memmove(ps->data, ps->data + 1, (ps->sz - 1)*sizeof(DataType));
ps->sz--;
}
//指定位置添加
void Insert(pSeqList ps, int pos, DataType x)
{
assert(ps != NULL);
Check(ps);
memmove(ps->data + pos + 1, ps->data + pos, (ps->sz - pos)*sizeof(DataType));
ps->data[pos] = x;
ps->sz++;
}
//查找
int Find(pSeqList ps, DataType x)
{
int i = 0;
assert(ps != NULL);
if (ps->sz == 0)
{
return -1;
}
for (i = 0; i < ps->sz; i++)
{
if (ps->data[i] == x)
{
return i;
}
}
return -1;
}
//指定删除
void Remove(pSeqList ps, DataType x)
{
int ret = -1;
assert(ps != NULL);
if (ps->sz == 0)
{
return;
}
ret = Find(ps, x);
if (ret != -1)
{
memmove(ps->data + ret, ps->data + ret + 1, (ps->sz - ret)*sizeof(DataType));
ps->sz--;
}
}
//指定删除全部
void RemoveAll(pSeqList ps, DataType x)
{
int i = 0;
assert(ps != NULL);
if (ps->sz == 0)
{
return;
}
for (i = 0; i < ps->sz; i++)
{
if (x == ps->data[i])
{
memmove(ps->data + i, ps->data + i + 1, (ps->sz - i-1)*sizeof(DataType));
ps->sz--;
i--;//防止被删除位置新的数被漏掉
}
}
}
//逆序
void ReverseList(pSeqList ps)
{
int left = 0;
int right = ps->sz - 1;
assert(ps != NULL);
if (ps->sz == 0)
{
return;
}
while (left < right)
{
int tmp = ps->data[left];
ps->data[left] = ps->data[right];
ps->data[right] = tmp;
left++;
right--;
}
}
//排序
void SortList(pSeqList ps)
{
int i = 0;
int j = 0;
assert(ps != NULL);
if (ps->sz == 0)
{
return;
}
for (i = 0; i < ps->sz - 1; i++)
{
for (j = 0; j < ps->sz - i - 1; j++)
{
if (ps->data[j]>ps->data[j + 1])
{
int tmp = ps->data[j];
ps->data[j] = ps->data[j + 1];
ps->data[j + 1] = tmp;
}
}
}
}
//二分查找
int BinarySearch(pSeqList ps, DataType x)
{
int left = 0;
int right = ps->sz - 1;
int mid = 0;
assert(ps != NULL);
if (ps->sz == 0)
{
return -1;
}
while (left < right)
{
mid = left + (right - left) / 2;
if (ps->data[mid] > x)
{
right = mid - 1;
}
else if (ps->data[mid] < x)
{
left = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
//销毁
void Distroy(pSeqList ps)
{
assert(ps != NULL);
free(ps->data);
ps->data = NULL;
ps->sz = 0;
ps->capacity = 0;
}
测试函数(test.c)部分
下边的注意一定要认真看!!!
下边的注意一定要认真看!!!
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include "SeqList.h"
void test1()
{
struct SeqList plist;
InitSeqlist(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 4);
PrintSeqlist(&plist);
PopBack(&plist);
PrintSeqlist(&plist);
PopBack(&plist);
PrintSeqlist(&plist);
PopBack(&plist);
PrintSeqlist(&plist);
PopBack(&plist);
PrintSeqlist(&plist);
PopBack(&plist);
PrintSeqlist(&plist);
Distroy(&plist);
}
void test2()
{
struct SeqList plist;
InitSeqlist(&plist);
PushFront(&plist, 1);
PushFront(&plist, 2);
PushFront(&plist, 3);
PushFront(&plist, 4);
PrintSeqlist(&plist);
PopFront(&plist);
PrintSeqlist(&plist);
PopFront(&plist);
PrintSeqlist(&plist);
PopFront(&plist);
PrintSeqlist(&plist);
PopFront(&plist);
PrintSeqlist(&plist);
PopFront(&plist);
PrintSeqlist(&plist);
Distroy(&plist);
}
void test3()
{
struct SeqList plist;
InitSeqlist(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 4);
PrintSeqlist(&plist);
Insert(&plist, 2, 6);
PrintSeqlist(&plist);
Distroy(&plist);
}
void test4()
{
struct SeqList plist;
InitSeqlist(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 4);
PrintSeqlist(&plist);
int ret = Find(&plist, 3);
//int ret = Find(&plist, 5);
printf("%d\n", ret);
Remove(&plist, 3);
PrintSeqlist(&plist);
/*Remove(&plist, 6);
PrintSeqlist(&plist);*/
Distroy(&plist);
}
void test5()
{
struct SeqList plist;
InitSeqlist(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 2);
PushBack(&plist, 4);
PushBack(&plist, 6);
PushBack(&plist, 2);
PrintSeqlist(&plist);
RemoveAll(&plist, 2);
PrintSeqlist(&plist);
Distroy(&plist);
}
void test6()
{
struct SeqList plist;
InitSeqlist(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 4);
PrintSeqlist(&plist);
ReverseList(&plist);
PrintSeqlist(&plist);
Distroy(&plist);
}
void test7()
{
struct SeqList plist;
InitSeqlist(&plist);
PushFront(&plist, 1);
PushFront(&plist, 2);
PushFront(&plist, 3);
PushFront(&plist, 4);
PrintSeqlist(&plist);
SortList(&plist);
PrintSeqlist(&plist);
Distroy(&plist);
}
void test8()
{
struct SeqList plist;
InitSeqlist(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 4);
PushBack(&plist, 5);
PushBack(&plist, 6);
PrintSeqlist(&plist);
int ret = BinarySearch(&plist, 5);
printf("%d\n", ret);
Distroy(&plist);
}
int main()
{
test1();//测试在后边添加和删除
//test2();//测试在前边添加和删除
//test3();//测试指定位置添加函数
//test4();//测试查找函数和指定删除某个数的函数,找到返回下标,没找到返回-1
//test5();//测试删除所有指定的某个值的函数
//test6();//测试逆序函数
//test7();//测试排序函数(从小到大排列)
//test8();//测试二分查找函数,找到返回下标,没找到返回-1
return 0;
}
注意:因为是动态开辟的内存,所以用完一定要记得释放这块动态开辟的内存。每一个测试函数都包含了销毁函数(里边包括了释放动态内存的函数),为了避免再一次使用已经释放了的空间导致程序崩溃,所以,测试函数一次只能调用一个,想要测试哪个函数的功能,在主函数里边将对应的那个测试函数放开就可以了。
运行结果:
PS:欢迎大家提出宝贵意见哦 ~