数据结构:存放数据的一种形式;
顺序表:将数据元素放在一块连续的内存存储空间,相邻数据元素的存放地址也相邻;
优:
- 空间利用率高(局部性原理,连续存放,命中率高);
- 存取速度高,通过下标直接存储;
缺:
- 进行插入,删除速度慢;(需遍历全部)
- 空间限制,不可更改;
链表:动态的空间分配,每个元素的存储空间分为两部分(1,存放数据元素 2,存放表示节点关系间的元素)
- 优:删除,插入方便,可更改空间大小;
- 缺:查找慢
静态顺序表
该顺序表可进行:
- 头部插入Pushfirst()
- 尾部插入Pushback()
- 尾部删除Popback
- 头部删除Popfirst()
- 在指定位置插入Insert()
- 显示ShowSeqlist()
- 在指定位置删除Erase()
- 查找元素Find()
- 删除元素Remove()
- 删除出现的相同的元素RemoveAll()
- 置空Empty()
- 求大小Size()
- 冒泡排序BubbleSort()
- 二分查找BinarySearch()
- 选择排序,Selectsort()
头文件”Seqlist.h”
#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#include"stdio.h"
#include"stdlib.h"
#include"assert.h"
#include"string.h"
#define MAX 10
#define type int
typedef struct Seqlist
{
type data[MAX];
type sz; //当前放了几个,头文件申明不可赋值
}Seqlist,*pSeqlist;
void InitSeqlist(pSeqlist p);
void Pushfirst(pSeqlist p,type n);
void Pushback(pSeqlist p, type n);
void ShowSeqlist(Seqlist seq);
void Popback(pSeqlist p);
void Popfirst(pSeqlist p);
int Find(Seqlist seq,type n);
void Insert(pSeqlist p, int pos, type n);//在指定位置插入
void Erase(pSeqlist p, int pos);//在指定下标删除该元素
void Remove(pSeqlist p,type d);//删除指定元素
void RemoveAll(pSeqlist p, type d);//删除所有出现的该元素
int Empty(pSeqlist p);//清空
int Size(pSeqlist p);
void BubbleSort(pSeqlist p);
int BinarySearch(pSeqlist p, type d);
void Selectsort(pSeqlist p);
void Select_sort(pSeqlist p);
#endif
源文件test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Seqlist.h"
void Pushfirst_test()
{
Seqlist seq;
InitSeqlist(&seq);
Pushfirst(&seq, 1);//头部插入
Pushfirst(&seq, 2);
Pushfirst(&seq, 3);
Pushfirst(&seq, 4);
Pushfirst(&seq, 5);
Pushfirst(&seq, 6);
ShowSeqlist(seq);
Popfirst(&seq);
ShowSeqlist(seq);
}
void test()
{
Seqlist seq;
InitSeqlist(&seq);
Pushback(&seq, 3);//尾部插入
Pushback(&seq, 2);
Pushback(&seq, 7);
Pushback(&seq, 4);
Pushback(&seq, 3);
Pushback(&seq, 3);
Pushback(&seq, 3);
ShowSeqlist(seq);
Selectsort(&seq);
ShowSeqlist(seq);
Popback(&seq);//尾部删除
ShowSeqlist(seq);
Pushfirst(&seq,0);//头部插入
ShowSeqlist(seq);
Popfirst(&seq);//头部删除,用&seq是由于删除会改变seq
ShowSeqlist(seq);
int x=Find(seq,3);
printf("%d\n", x);
Insert(&seq, 2, 8);//在下标为2的位置之前插入8
ShowSeqlist(seq);
Erase(&seq,2);
ShowSeqlist(seq);
Remove(&seq,3);
ShowSeqlist(seq);
RemoveAll(&seq,3);
ShowSeqlist(seq);
Empty(&seq);
int x=Size(&seq);
printf("%d\n", x);
BubbleSort(&seq);
/*int x=Binary_Search(&seq, 4, 0, 5);
if (x != -1)
{
printf("找到了,下标为%d\n",x);
}
ShowSeqlist(seq);*/
/*int x= BinarySearch(&seq,5);
if (x != -1)
{
printf("找到了,下标为%d\n", x);
}*/
ShowSeqlist(seq);
Select_sort(&seq);
}
int main()
{
test();
Pushfirst_test();
system("pause");
return 0;
}
源文件 Seqlist.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void InitSeqlist(pSeqlist p)
{
p->sz = 0;
memset(p->data, 0, sizeof(p->data)) ;
}
void Pushback(pSeqlist p, type n)
{
assert(p != NULL);
if (p->sz == MAX)//已有元素为最大值;
{
printf("已满,插不进\n");
return;//已满,,不做处理;
}
else
{
p->data[p->sz] = n;//把最后一个元素插进去
p->sz++;
}
}
void ShowSeqlist(Seqlist seq)
{
for (int i = 0; i < seq.sz; i++)
{
printf("%d ", seq.data[i]);
}
printf("\n");
}
void Popback(pSeqlist p)
{
assert(p);
if (p->sz == 0)
{
printf("顺序表已空\n");
return;
}
p->data[p->sz - 1] = 0;
p->sz--;
printf("\n");
}
void Pushfirst(pSeqlist p,type n)
{
assert(p);
if (p->sz == MAX)
{
printf("通讯录已满,不可插\n");
return;//不返回
}
else
{
for (int i = p->sz; i > 0; i--)//i = p->sz i>0,i最小为1,则i-1下标为0
{
p->data[i] = p->data[i - 1];
}
p->data[0] = n;
p->sz++;
}
printf("\n");
}
void Popfirst(pSeqlist p)
{
assert(p);
if (p->sz == 0)
{
printf("通讯录已空,不可删除\n");
return;
}
else
{
for (int i = 0; i < p->sz; i++)
{
p->data[i] = p->data[i + 1];
}
p->sz--;
}
printf("\n");
}
int Find(Seqlist seq, type n)//返回下标
{
for (int i = 0; i < seq.sz; i++)
{
if (seq.data[i] == n)
{
printf("找到了\n");
return i;
}
}
return -1;//没找到
printf("\n");
}
void Insert(pSeqlist p, int pos, type n)//在指定位置插入,在pos位置之前插入,
{
assert(p);
if (p->sz == MAX)
{
printf("顺序表已满,不可插入\n");
return;
}
for (int i = p->sz; i > pos; i--)
{
p->data[i] = p->data[i - 1];
}
p->data[pos] = n;
p->sz++;
}
void Erase(pSeqlist p, int pos)//在指定位置删除
{
assert(p);
if (p->sz == 0)
{
return;
}
for (int i = pos; i < p->sz-1; i++)
{
p->data[i] = p->data[i + 1];//删除把后面元素往前挪,覆盖到前面,则删除了;
}
p->sz--;
}
void Remove(pSeqlist p, type d)//删除某个元素
{
assert(p != NULL);
int pos = 0;
int i = 0;
if (p->sz == 0)
{
printf("顺序表已空,不可删\n");
return;
}
for (int i = 0; i < p->sz; i++)//先查找该元素是否存在,把该元素的下标记住,在for循环推出后,变量不销毁,
{
if (p->data[i] == d)
{
pos = i;
}
}
if (pos == p->sz)
{
printf("不存在\n");
return;
}
else
{
for (int j = pos; j < p->sz-1; j++)//把该元素后面的元素往前挪,覆盖到要删除元素;
{
p->data[j] = p->data[j + 1];//p->data[j+1]j<p->sz-1,则j最大为p->sz-2,j+1为p->sz-1为最后一个元素,把最后一个元素及之前的元素往前挪
}
p->sz--;
}
}
void Remove(pSeqlist p, type d)
{
Seqlist seq;
assert(p);
int pos = 0;
pos = Find(seq, 5);//find返回的是下标
if (pos != -1)
{
Erase(p, pos);
}
else
{
printf("要删除的元素不存在\n");
}
}
void RemoveAll(pSeqlist p, type d)//删除要删除的元素所出现的所有
{
assert(p);
if (p->sz == 0)
{
printf("顺序表已空,不可删除\n");
return;
}
for (int i = 0; i < p->sz; i++)
{
if (p->data[i] == d)
{
int pos = i;
for (int j = pos; j < p->sz-1; j++)//找到该元素,记住下标,把后面的元素依次往前挪,直到挪在该元素上
{
p->data[j] = p->data[j + 1];//j<p->sz-1则j+1最大为p->sz-1
}
i--;//删除元素后,元素向前挪,此时,pos位置的值以改变,应当i--,再进行i++返回到当前位置,防止55这种形式
p->sz--;//删除元素后个数--
}
}
}
void RemoveAll(pSeqlist p, type d)
{
Seqlist seq;
assert(p);
int pos = 0;
if (p->sz == 0)
{
printf("不可删除\n");
return;
}
while ((pos = Find(seq, 3)) != -1)//Find返回!=-1,则表示找到了,下表为pos,则删除一个
{
Erase(p, pos);
}
}
int Empty(pSeqlist p)//置空
{
assert(p);
if (p->sz != 0)
{
for (int i = 0; i < p->sz; i++)
{
p->data[i] = 0;
}
p->sz = 0;
}
return 1;
}
int Size(pSeqlist p)//求顺序表大小
{
if (p->sz == 0)
{
return 0;
}
else
{
return p->sz;
}
}
void BubbleSort(pSeqlist p)//冒泡排序
{
assert(p);
for (int i = 0; i < p->sz-1; i++)//7个数有6趟
{
int flag = 0;
for (int j = 0; j < p->sz-1 - i; j++)//j < p->sz-1 - i共7个数,其余位置补0,不比较0,则j+1应最大为p->sz-1,则j最大为p->sz-2,即j<p->sz-1
{
if (p->data[j]>p->data[j + 1])
{
int tmp = p->data[j];
p->data[j] = p->data[j + 1];
p->data[j + 1] = tmp;
flag = 1;
}
}//里面for循环比较大小,交换
if (flag == 0)//代表这一趟序列大小已经排好,不需要下次再比较 124567
return;
}
}
int BinarySearch(pSeqlist p, type d)//二分查找,序列应为有序
{
assert(p);
int left = 0;
int right = p->sz - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (p->data[mid] > d)
{
right = mid--;
}
else if (p->data[mid] < d)
{
left = mid + 1;
}
else
{
//printf("找到了\n");
return mid;
}
}
return -1;
}
//二分查找的递归
int Binary_Search(pSeqlist p,type n,int left,int right)
{
int mid = 0;
if (left > right)
return -1;
mid = left + (right - left) / 2;
if (p->data[mid] < n)
{
return Binary_Search(p, n, mid + 1, right);
}
else if (p->data[mid]>n)
{
return Binary_Search(p, n, left, mid - 1);
}
else
{
return mid;
}
}
void Selectsort(pSeqlist p)// 选择排序,一趟处理一个元素,共走p->sz-1趟
{
assert(p);
int i = 0;
for (i = 0; i < p->sz-1; i++)
{
int Maxpos = 0;
for (int j = 1; j < p->sz - i; j++)
{
if (p->data[j]>p->data[Maxpos])
Maxpos = j;//一趟里面最大值的下标记录
}
if (Maxpos != p->sz - 1-i)//若写成p->sz-1,则Maxpos一直与全部最后一个交换,应当与每趟的最后一个比较
{
int tmp = p->data[Maxpos];
p->data[Maxpos] = p->data[p->sz - 1];
p->data[p->sz - 1] = tmp;
}
}//一趟结束
}
void Swap(type *p1, type *p2)
{
type q = *p1;
*p1 = *p2;
*p2 = q;
}
void Select_sort(pSeqlist p)//走一趟处理两个元素,把最大的放在 最后,把最小的放在最前面
{
int left = 0;
int right = p->sz - 1;
while (left < right)
{
int Maxpos=left;//每次循环
int Minpos = left;
int i = 0;
for (i = left+1; i <= right; i++)
{
if (p->data[i]>p->data[Maxpos])
Maxpos = i;
if (p -> data[i] < p->data[Minpos])
{
Minpos = i;
}
}//一趟结束
if (Minpos !=left )
{
Swap(p->data[Minpos], p->data[left]);
}
if (Maxpos == left)
{
Maxpos = Minpos;
}
if (Maxpos != right)
{
Swap(p->data[Maxpos], p->data[right]);
}
left++;
right--;
}
}