顺序表实现下面功能
//初始化
void InitSeqList(PSeqList pSeq);
//尾部插入
void PushBack(PSeqList pSeq, DataType data);
//尾部删除
void PopBack(PSeqList pSeq);
//头部插入
void PushFront(PSeqList pSeq, DataType data);
//头部删除
void PopFront(PSeqList pSeq);
//查找指定元素
int Find(PSeqList pSeq, DataType data);
//指定位置插入
void Insert(PSeqList pSeq, int pos, DataType data);
//删除指定位置元素
void Erase(PSeqList pSeq, int pos);
//删除指定元素
void Remove(PSeqList pSeq, DataType data);
//删除所有的指定元素
void RemoveAll(PSeqList pSeq, DataType data);
//返回顺序表的大小
int Size(PSeqList pSeq);
//判断顺序表是否为空
int Empty(PSeqList pSeq);
//冒泡排序
void BubbleSort(PSeqList pSeq);
//选择排序
void SelectSort(PSeqList pSeq);
//选择排序的优化
void SelectSortOP(PSeqList pSeq);
//二分查找
int BinarySearch(PSeqList pSeq, DataType data);
//二分查找递归写法
int BinarySearch_R(pSeqList pSeq, int left, int right, DataType d);
//打印
void PrintSeqList(PSeqList pSeq);
SeqList.h 文件
#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
typedef int DataType;//定义元素的类型
#define DEFAULT_SZ 3
//顺序表的定义
typedef struct{
DataType *data; //存放数据
int sz; //定义一个变量,用来记录顺序表元素的大小
int capacity; //定义一个变量,用来记录顺序表的容量
}SeqList,*PSeqList;
//内存开辟
void DynamicOpening(PSeqList pSeq);
//销毁
void Destory(PSeqList pSeq);
//打印
void PrintSeqList(PSeqList pSeq);
//初始化
void InitSeqList(PSeqList pSeq);
//尾部插入
void PushBack(PSeqList pSeq, DataType data);
//尾部删除
void PopBack(PSeqList pSeq);
//头部插入
void PushFront(PSeqList pSeq, DataType data);
//头部删除
void PopFront(PSeqList pSeq);
//查找指定元素
int Find(PSeqList pSeq, DataType data);
//指定位置插入
void Insert(PSeqList pSeq, int pos, DataType data);
//删除指定位置元素
void Erase(PSeqList pSeq, int pos);
//删除指定元素
void Remove(PSeqList pSeq, DataType data);
//删除所有的指定元素
void RemoveAll(PSeqList pSeq, DataType data);
//返回顺序表的大小
int Size(PSeqList pSeq);
//判断顺序表是否为空
int Empty(PSeqList pSeq);
//冒泡排序
void BubbleSort(PSeqList pSeq);
//选择排序
void SelectSort(PSeqList pSeq);
//选择排序的优化
void SelectSortOP(PSeqList pSeq);
//二分查找
int BinarySearch(PSeqList pSeq, DataType data);
//二分查找递归写法
int BinarySearch_R(PSeqList pSeq, int left, int right, DataType d);
#endif //__SEQLIST_H__
SeqList.c 文件
注意:在实现插入操作的时候都必须判断顺序表是否表满,在删除操作的时候必须判断是否表空
在每次在实现函数功能之前使用assert()断言,用于检查“不应该”出现的情况
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//内存销毁
void Destory(PSeqList pSeq)
{
DataType *p = pSeq->data;
assert(pSeq);
free(p);
pSeq->data = NULL;
pSeq->capacity = 0;
pSeq->sz = 0;
printf("内存销毁成功!\n");
}
//内存开辟
void DynamicOpening(PSeqList pSeq)
{
static int flag = 1;
//断言
assert(pSeq);
if (pSeq->sz == pSeq->capacity)
{
//创建临时变量来防止内存开辟失败
DataType *tmp = (DataType *)realloc(pSeq->data, sizeof(DataType)*(pSeq->capacity+1));
if (tmp == NULL)
{
perror("use realloc");
exit(EXIT_FAILURE);
}
else
{
if (flag > 0)
{
printf("内存开辟成功!\n");
flag--;
}
pSeq->data = tmp;
}
pSeq->capacity += 1;
}
}
//打印
void PrintSeqList(PSeqList pSeq)
{
int i = 0;
assert(pSeq);
for(i = 0; i < pSeq->sz; i++)
{
printf("%d-->", pSeq->data[i]);
}
printf("\n");
printf("元素个数为:%d",pSeq->sz);
printf("\n");
}
//初始化
void InitSeqList(PSeqList pSeq)
{
assert(pSeq);
pSeq->data = (DataType *)malloc(sizeof(DataType)*DEFAULT_SZ);
if (pSeq->data == NULL)
{
perror("use malloc");
exit(EXIT_FAILURE);
}
pSeq->sz = 0;
pSeq->capacity = DEFAULT_SZ;
}
//尾部插入
void PushBack(PSeqList pSeq, DataType data)
{
assert(pSeq);
//判断表是否已满
if (pSeq->sz == pSeq->capacity)
{
DynamicOpening(pSeq);
}
pSeq->data[pSeq->sz] = data;
pSeq->sz++;
}
//尾部删除
void PopBack(PSeqList pSeq)
{
assert(pSeq);
if(pSeq->sz == 0)
{
printf("表为空,无法删除\n");
}
pSeq->sz--;
}
//头部插入
void PushFront(PSeqList pSeq, DataType data)
{
int i = 0;
assert(pSeq);
if(pSeq->sz == pSeq->capacity)
{
DynamicOpening(pSeq);
}
for(i = pSeq->sz; i > 0; i--)
{
pSeq->data[i] = pSeq->data[i-1];
}
pSeq->data[0] = data;
pSeq->sz++;
}
//头部删除
void PopFront(PSeqList pSeq)
{
int i = 0;
assert(pSeq);
if(pSeq->sz == 0)
{
printf("表空,无法删除\n");
}
for(i = 1; i < pSeq->sz; i++)
{
pSeq->data[i-1] = pSeq->data[i];
}
pSeq->sz--;
}
//查找指定元素
int Find(PSeqList pSeq, DataType data)
{
int i = 0;
assert(pSeq);
if (pSeq->sz == 0)
{
printf("表空,查找失败!\n");
}
for(i = 0; i < pSeq->sz; i++)
{
if(pSeq->data[i] == data)
{
return i;
}
}
return -1;
}
//指定位置插入
void Insert(PSeqList pSeq, int pos, DataType data)
{
int i = 0;
assert(pSeq);
if(pSeq->sz == pSeq->capacity)
{
DynamicOpening(pSeq);
}
for(i = pSeq->sz-1; i >= pos-1; i--)
{
pSeq->data[i+1] = pSeq->data[i];
}
pSeq->data[pos-1] = data;
pSeq->sz++;
printf("元素插入成功!\n");
}
//删除指定位置元素
void Erase(PSeqList pSeq, int pos)
{
int i = 0;
assert(pSeq);
if(pSeq->sz == 0)
{
printf("表空,删除失败\n");
}
for(i = pos; i <= pSeq->sz; i++)
{
if (pSeq->data[i - 1] == pSeq->data[i])
{
pSeq->sz--;
return;
}
}
printf("要删除的位置不存在!\n");
}
//删除指定元素
void Remove(PSeqList pSeq, DataType data)
{
int i = 0;
int ret = 0;
assert(pSeq);
ret = Find(pSeq, data);
if(ret == -1)
{
printf("查找到元素不存在\n");
}
else
{
for(i = ret; i < pSeq->sz; i++)
{
pSeq->data[i] = pSeq->data[i+1];
}
pSeq->sz--;
}
}
//删除所有的指定元素
void RemoveAll(PSeqList pSeq, DataType data)
{
int i = 0;
int j = 0;
assert(pSeq);
for(i = 0; i < pSeq->sz; i++)
{
if(pSeq->data[i] == data)
{
for(j = i; j < pSeq->sz-1; j++)
{
pSeq->data[j] = pSeq->data[j+1];
}
i--;
pSeq->sz--;
}
}
}
//返回顺序表的大小
int Size(PSeqList pSeq)
{
assert(pSeq);
return pSeq->sz;
}
//判断顺序表是否为空
int Empty(PSeqList pSeq)
{
assert(pSeq);
if(pSeq->sz == 0)
{
return -1;
}
else
{
return pSeq->sz;
}
}
//冒泡排序
void BubbleSort(PSeqList pSeq)
{
int i = 0;
int j = 0;
int ret = 0;
DataType cmd = 0;
assert(pSeq);
ret = Empty(pSeq);
if(ret == -1)
{
printf("表空,无法排序\n");
}
else
{
for(i = 0; i < pSeq->sz; i++)
{
for(j = 1; j < pSeq->sz-i; j++)
{
if(pSeq->data[j-1] > pSeq->data[j])
{
cmd = pSeq->data[j-1];
pSeq->data[j-1] = pSeq->data[j];
pSeq->data[j] = cmd;
}
}
}
}
}
/*
选择排序的基本思想:第1趟,在待排序记录r[1]--r[n]中选出最小的记录,将它与r[1]交换;
第2趟,在待排序记录r[2]--r[n]中选出最小的记录,将它与r[2]交换;以此类推,
第i趟在待排序记录r[i]--r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。
时间复杂度O(n) = n;
*/
void SelectSort(PSeqList pSeq)
{
int min = 0;
int i = 0;
int j = 0;
int count = pSeq->sz;
DataType cmd = 0;
int ret = 0;
assert(pSeq);
ret = Empty(pSeq);
if(ret == -1)
{
printf("表空,无法选择排序\n");
}
for(i = 0; i < count-1; i++)
{
min = i;
for(j = i+1; j < count; j++)
{
if(pSeq->data[j] < pSeq->data[min])
{
min = j;
}
}
cmd = pSeq->data[i];
pSeq->data[i] = pSeq->data[min];
pSeq->data[min] = cmd;
}
}
//选择排序的优化
//思想:相当于遍历一遍同时记录最大值和最小值,时间复杂度 O(n) = 2/n;
void SelectSortOP(PSeqList pSeq)
{
int start = 0;
int ret = 0;
int end = pSeq->sz-1;
//记录最小值的下标
int min = 0;
//记录最大值的下标
int max = 0;
int i = 0,j = 0;
int rmt = 0;
assert(pSeq);
ret = Empty(pSeq);
if(rmt == -1)
{
printf("表空,无法选择排序\n");
}
//循环控制条件,每循环次取出一组最大值和最小值
while(start < end)
{
for(i = start; i < end; i++)
{
min = start;
max = start;
for(j = start+1; j < end+1; j++)
{
if(pSeq->data[j] > pSeq->data[max])
{
max = j;
}
if(pSeq->data[j] < pSeq->data[min])
{
min = j;
}
}
if(min != start)
{
ret = pSeq->data[min];
pSeq->data[min] = pSeq->data[start];
pSeq->data[start] = ret;
}
//如果最大值下标就等于start,当最小值交换之后,start被改变,则必须更新max,否则max会被min覆盖
if(max == start)
{
max = min;
}
if(max != end)
{
ret = pSeq->data[max];
pSeq->data[max] = pSeq->data[end];
pSeq->data[end] = ret;
}
}
start++;
end--;
}
}
//二分查找
int BinarySearch(PSeqList pSeq, DataType data)
{
int i = 0;
int j = 0;
int left = 0;
int right = pSeq->sz-1;
int mid = 0;
int ret = 0;
assert(pSeq);
ret = Empty(pSeq);
if(ret == -1)
{
printf("表空,无法选择排序\n");
}
while(left < right)
{
mid = (left+(right-left))>>1;
if(pSeq->data[mid] > data)
{
right = mid+1;
}
else if(pSeq->data[mid] < data)
{
left = mid-1;
}
else if(pSeq->data[mid] == data)
{
return mid;
}
else
{
break;
}
}
return -1;
}
//二分查找递归写法
int BinarySearch_R(PSeqList pSeq, int left, int right, DataType d)
{
int mid;
assert(pSeq);
while(left < right)
{
//mid = (left+(right-left))/2;
mid = (left+(right-left))>>1;
if(pSeq->data[mid] > d)
{
BinarySearch_R(pSeq, left, mid-1, d);
}
else if(pSeq->data[mid] < d)
{
BinarySearch_R(pSeq, mid+1, right, d);
}
else if(pSeq->data[mid] == d)
{
return mid;
}
else
{
break;
}
}
return -1;
}
test.c 文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
void test()
{
SeqList pSeq;
int left = 0;
int right = 0;
int ret = 0;
InitSeqList(&pSeq);
PushBack(&pSeq, 1);
PushBack(&pSeq, 7);
PushBack(&pSeq, 4);
PushBack(&pSeq, 3);
PushBack(&pSeq, 5);
PushBack(&pSeq, 6);
// PrintSeqList(&pSeq);
// PopBack(&pSeq);
// PrintSeqList(&pSeq);
// PushFront(&pSeq, 5);
// PrintSeqList(&pSeq);
// PopFront(&pSeq);
// PrintSeqList(&pSeq);
// Insert(&pSeq, 1, 8);
// Erase(&pSeq, 4);
// Remove(&pSeq, 3);
// RemoveAll(&pSeq, 3);
// RemoveAll(&pSeq, 2);
// Size(&pSeq);
// BubbleSort(&pSeq);
// SelectSort(&pSeq);
// SelectSortOP(&pSeq);
// ret = BinarySearch(&pSeq, 3);
// right = Size(&pSeq)-1;
// ret = BinarySearch_R(&pSeq, left, right, 3);
// PrintSeqList(&pSeq);
// Destory(&pSeq);
// printf("%d\n",ret);
}
int main()
{
test();
system("pause");
return 0;
}