静态顺序表的实现
来源:互联网 发布:c语言无线循环 编辑:程序博客网 时间:2024/05/22 08:18
#define _CRT_SECURE_NO_WARNINGS 1#include"stdio.h"#include"string.h"#include"assert.h"#include"stdlib.h"#pragma warning(disable:4996)#define MAX_SIZE 10typedef int DataType;typedef struct SeqList{ DataType arr[MAX_SIZE];//建立一个数组,用于存储数据 size_t size;//用于声明数组中所含元素的个数}SeqList,*pSeqList;//初始化顺序表void InitSeqList(SeqList* seqList){ assert(seqList);//用于判断顺序表是否为空 memset(seqList,0,sizeof(DataType)*MAX_SIZE);//用来对一段内存空间全部设置为某个字符, //一般用在对定义的字符串进行初始化为‘ ’或‘/0’ seqList->size = 0;}//在顺序表的尾部插入元素datavoid PushBack(SeqList* seqList, DataType data){ assert(seqList); if (seqList->size == MAX_SIZE) { printf("顺序表已满,不能再插入其他的元素!"); return; } seqList->arr[seqList->size] = data; seqList->size++;}//将顺序表尾部的元素删除void PopBack(SeqList* seqList){ assert(seqList); if (seqList->size==0) { printf("顺序表为空,不能进行删除元素!\n"); return; } seqList->size--; //此时顺序表存储的数据元素并没有被真是的删除,但是因为顺序表中此时的元素个数少了一个 //使最后的那个元素相当于无效元素,这就达到了删除的效果}//顺序表的头部插入元素datavoid PushFront(SeqList* seqList, DataType data){ assert(seqList); size_t index = seqList->size - 1; if (seqList->size >= MAX_SIZE) { printf("顺序表已满,不能再插入其他元素!"); return; } for (index = seqList->size - 1; index >= 0; index--) { seqList->arr[index + 1] = seqList->arr[index]; } seqList->arr[0] = data;//顺序表中原有的所有元素都要向后挪一个位置,避免被覆盖 seqList->size++;}//顺序表的头部的元素删除void PopFront(SeqList *seqList){ size_t index = 0; assert(seqList); if (0 == seqList->size) { printf("顺序表为空,不能进行删除!"); return; } for (index = 0; index < seqList->size; index++) { seqList->arr[index] = seqList->arr[index+1]; } seqList->size--;}//顺序表中查找数据data,返回该元素在顺序表中的位置int Find(SeqList *seqList, DataType data){ assert(seqList); size_t index = 0; for (index = 0; index < seqList->size; index++) { if (seqList->arr[index]==data) { return index + 1; } } return -1;}//在顺序表的pos位置上插入元素datavoid Insert(SeqList *seqList,size_t pos,DataType data){ assert(seqList); size_t index = 0; if (pos > seqList->size) { printf("位置不正确,请重新选择位置!");//要保证数据元素插入后所有元素都是连续的,否则不能叫作顺序表 return; } if (seqList->size>=MAX_SIZE) { printf("顺序表已满,不能再插入其他元素!"); return; } for (index = seqList->size - 1; index >= pos; index--) { seqList->arr[index+1] = seqList->arr[index]; } seqList->arr[index] = data; seqList->size++;}//删除顺序表pos位置上的元素void Erase(SeqList* seqList, size_t pos){ assert(seqList); size_t index = 0; if (pos > seqList->size) { printf("位置不正确,请重新输入位置!"); return; } for (index = pos - 1; index < seqList->size - 1; index++) { seqList->arr[index] = seqList->arr[index+1]; } seqList->size--;}//移除顺序表中的元素datavoid Remove(SeqList* seqList, DataType data){ assert(seqList); size_t index = 0; size_t temp = 0; for (index = 0; index < seqList->size; index++) { if (data == seqList->arr[index]) { for (temp = index; temp < seqList->size - 1; temp++) { seqList->arr[temp] = seqList->arr[temp + 1]; } } seqList->size--; return; }}//移除顺序表中的所有值为data的元素void RemoveAll(SeqList* seqList, DataType data){ assert(seqList); size_t index = 0; size_t rem = 0; for (; index < seqList->size; index++) { if (seqList->arr[index] == data) { for (rem = index; rem < seqList->size - 1; rem++) //可以考虑是否可以递归 { seqList->arr[rem] = seqList->arr[rem + 1]; } //当在顺序表中找到了该数时,就把该数之后的所有元素全部向前挪一个元素的位置,把原数据覆盖即可达到移除的目的 seqList->size--; index--; //index--是因为删除一个元素之后,后面的元素都会前移,那么可能前移元素中的最前面的元素和我们要删除的元素 //的值是一样的,而此时index++了,它的值是前移元素中的第二个元素的值,因此要给index--,使它的值为前移元素 //中的第一个元素的值 //因为这个函数是要删除顺序表中所有的值为data的元素,所以在这儿不能直接删除一个就返回了,而是知道遍历所有 //元素,删除对应的元素,才会返回 } }}void Swap(int *num1, int *num2){ int temp = *num1; //变量是在需要交换两个元素位置时充当临时变量的,因为也不知道元素的符号,所以用int类型而非size_t *num1 = *num2; *num2 = temp;}//选择排序void SelectSort(pSeqList seqList){ assert(seqList); size_t num = 0; size_t index = 0; size_t end = seqList->size; for (; num < (seqList->size) / 2; num++) { size_t min = num; size_t max = num; for (index = num + 1; index < end; index++) { min = seqList->arr[min] < seqList->arr[index] ? min : index; max = seqList->arr[max] > seqList->arr[index] ? max : index; //每次比较两个元素,把比较完成后最小和最大的元素的下标保存起来,下一次比较时比较的两个对象分别是保存的下 //标对应的元素和还没有进行比较的所有元素中最前面的那一个元素(当然,也可以是未进行比较的所有元素中的任意一个) } Swap(&seqList->arr[min], &seqList->arr[num]); Swap(&seqList->arr[max], &seqList->arr[--end]); //注意这儿的--end是为了使下一次循环里的比较范围缩小, //同时也为了这儿取得是正确的下标值 //把最小和最大的元素交换到对应的位置去 }}//冒泡排序void BorbbleSort(pSeqList seqList) //排序为从小到大{ size_t index = 0; size_t num = 0; int flag = 1; assert(seqList); while (flag == 1) //对冒泡排序的优化,当某一趟排序时发现没有发生交换的情况,说明此时已经排序成功,那么就可以 //不用再进入下一趟排序,直接跳出循环,执行下面的操作 { for (num = 0; num < seqList->size - 1; num++) //思考冒泡排序两个循环的次数个应该各是多少 { for (index = 0; index < seqList->size - num - 1; index++) //不减1可能会造成越界访问 { if (seqList->arr[index]>seqList->arr[index + 1]) { Swap(&seqList->arr[index], &seqList->arr[index + 1]); //每次比较相邻两个元素,若前面的元素大于后面的,则交换两个元素的位置 flag = 1; } } } }}//查找有序顺序表中的元素dataint BinarySearch(SeqList* seqList, DataType data) //二分法在顺序表中找一个数{ int left = 0; int right = seqList->size - 1; assert(seqList); if (seqList->size==0) { return -1; //因为此时顺序表里没有数据,而seqList->size是无符号整型,减1的话出来的值是一个非常大的值,所以为了 //保证函数的正确性,在顺序表无数据时,直接返回 } while (left <= right) //注意right的取值对此处是用:left <= right还是left < right的影响 { int mid = left + (right - left) / 2; //没有写成mid = (left + right) / 2是因为害怕怕两数直接相加会溢出 if (seqList->arr[mid] == data) { return mid; } else if (seqList->arr[mid] > data) { right = mid - 1; //因为排序的函数是把顺序表的元素由小到大排列的 } else { left = mid + 1; } } return -1; //当没有找到要查找的数时,返回一个负值,以声明要查找的元素在顺序表中不存在,因为要是找到了, //返回一个数的位置,那么不会小于0}//打印顺序表void PrintSeqList(SeqList* seqList){ size_t index = 0; for (index=0; index < seqList->size; index++) { printf("%d ", seqList->arr[index]); return; } printf("\n");}SeqList seqList;//测试尾插与尾删函数void TestFun1(){ InitSeqList(&seqList); PushBack(&seqList, 1); PushBack(&seqList, 2); PushBack(&seqList, 3); PushBack(&seqList, 4); PrintSeqList(&seqList); PopBack(&seqList); PopBack(&seqList); PrintSeqList(&seqList);}//测试头插与头删函数void TestFun2(){ InitSeqList(&seqList); PushFront(&seqList, 1); PushFront(&seqList, 2); PushFront(&seqList, 3); PushFront(&seqList, 4); PrintSeqList(&seqList); PopFront(&seqList); PopFront(&seqList); PrintSeqList(&seqList);}//测试任意位置查找插入删除函数void TestFun3(){ int ret = 0; InitSeqList(&seqList); PushFront(&seqList, 1); PushFront(&seqList, 2); PushFront(&seqList, 3); PushFront(&seqList, 4); ret = Find(&seqList, 4); Insert(&seqList, 3, 5); Erase(&seqList, 5); printf("%d\n", ret); PrintSeqList(&seqList);}//测试移除函数void TestFun4(){ InitSeqList(&seqList); PushFront(&seqList, 1); PushFront(&seqList, 2); PushFront(&seqList, 2); PushFront(&seqList, 4); PushFront(&seqList, 1); PushFront(&seqList, 2); PushFront(&seqList, 2); PushFront(&seqList, 4); Remove(&seqList, 2); PrintSeqList(&seqList); RemoveAll(&seqList, 2); PrintSeqList(&seqList);}//测试排序与二分查找函数void TestFun5(){ int ret = 0; InitSeqList(&seqList); PushFront(&seqList, 3); PushFront(&seqList, 9); PushFront(&seqList, 1); PushFront(&seqList, 4); PushFront(&seqList, 2); PushFront(&seqList, 8); PushFront(&seqList, 7); PushFront(&seqList, 0); SelectSort(&seqList); //BorbbleSort(&seqList); ret = BinarySearch(&seqList, 1); printf("%d\n", ret); PrintSeqList(&seqList);}int main(){ //TestFun1(); //TestFun2(); //TestFun3(); //TestFun4(); TestFun5(); system("pause"); return 0;}
阅读全文
0 0
- 静态顺序表的实现
- 静态顺序表的实现
- 静态顺序表的实现
- 静态顺序表的实现
- 静态顺序表的实现
- 静态顺序表的实现
- 静态顺序表的实现
- 静态顺序表的实现
- 静态顺序表的实现
- 静态顺序表实现简单的通讯录
- C::静态顺序表的实现
- 顺序表的静态和动态实现
- C语言静态顺序表的实现
- 静态顺序表的简单实现
- 静态顺序表接口的简单实现
- 静态顺序表的c实现
- SeqList 顺序表的静态实现
- 静态顺序表的C语言实现
- angular-cli
- Ubuntu配置JAVA环境变量
- 21.最后一篇csdn博客
- 远程Linux上搭建ftp服务器
- FTP服务器的上传
- 静态顺序表的实现
- linux 进程间通讯方式
- day1
- 2017-11-21 background-position的应用
- ORACLE EBS常用表及查询语句(最终整理版)
- 第一次在leetcode上做hard级别的题目
- 前端面试题目总结
- list
- linux下卸载apache方法小结