什么是顺序表?
顺序表是线性表的一种,以数组的方式表示。即内存连续且存储的数据元素类型相同
顺序表可以看做一个数组,只是我们一开始学数组的时候数组中存储的是简单的数据类型,如int、char等,现在顺序表中存数的是一个结构体数据。结构体数据又是由多个以简单数据类型为基础的数据项组成的。当定义了一个该数据结构体变量时,该变量就是一个数据元素,结构体内的数据项就是该数据元素的基本属性。当有多个这种数据元素时,可以将它们存放在一个结构体数组中,这时这个结构体数组就是一个数据对象
从内存上去看,每一个数据项的空间分配都是线性的,几块数据项又组成了一个数据元素。所以可以发现,对结构体的访问和操作都可以用指针来实现
顺序表结构体声明
typedef struct sequenList{//数据
//数据项
INT data[N];
int last;//数组data的最后一个数据的下标
int lenth;//数组的大小
}LIST, *SLIST;
typedef重命名:将
struct sequenList
重命名为LIST
,将LIST*
重命名为SLIST
顺序表的操作
基本操作:创建、插入、删除、遍历(打印)、查找、修改、排序、合并等
创建一个顺序表
LIST *creat()
{
LIST *list = (LIST *)malloc(sizeof(LIST));
memset(list->data,0,sizeof(INT)*N);
list->last = -1;
list->lenth = 0;
return list;
}
创建思路:
- 动态内存分配
- 数据项初始化
- 返回新开辟空间的首地址
顺序表判空
int isEnpty(LIST *list)
{
return list->lenth==0 ? 1 : 0;
}
根据数据项的属性来判断
顺序表判满
int isFull(LIST *list)
{
if(list->lenth == N)
return 1;
else
return 0;
}
根据顺序表长度是否达到分配空间容量极限来判断
尾插法
void tailInsert(LIST *list,INT val)
{
list->last++;
list->data[list->last] = val;
list->lenth++;
}
相当于给数组中加入新的值。先要操作下标,后赋值
在给定位置插入数据元素
void insert(LIST *list,int position,INT val)
{
int i;
if(isFull(list))
printf("表满\n");
if(position<0 && position>list->last)
{
printf("位置不合法\n");
}
else{
for(i=list->lenth;i>position;i--)
{
list->data[i] = list->data[i-1];
}
list->data[position] = val;
list->lenth++;
list->last++;
}
}
1、判断表是否还有空间可以插入
2、判断给的位置是否可以插入
3、插入操作:从给定位置开始,数据依次往后移一位,腾出给定位置后插入,并修改相应数据项改变量
从尾部删除一个元素
void deletList(LIST *list)
{
if(isEnpty(list))
printf("空表\n");
else
{
INT *p = &(list->data[0]);
bzero(p+list->last,sizeof(INT));
list->last--;
list->lenth--;
}
}
若表不为空,则用到了清空bzero函数
按照位置删除数据
void deletBypos(LIST *list,int position)
{
int i;
if(isEnpty(list))
printf("表空");
if(position<=0 && position>list->last)
printf("位置不合法");
else{
for(i=position;i<list->last;i++)
{
list->data[i] = list->data[i+1];
}
if(position == list->last)
deletList(list);
list->last--;
list->lenth--;
}
}
1、判断表空否和位置合法否
2、采用从该位置开始,后一项依次赋值覆盖前一项操作,并删除最后一个数据元素,最后修改相应数据项
删除表中有重复的数据,只留一个
void deletRepetitionData(LIST *list,INT data)
{
int i,j;
if(isEnpty(list))
printf("表空\n");
else{
for(i=0;i<list->last;i++)
{
for(j=i+1;j<=list->last;j++)
{
if(list->data[i]==list->data[j])
deletBypos(list,j);
//printf("i=%d j=%d\n",i,j);//test
//printList(list);//test
}
if(list->data[i] == list->data[--j])
deletList(list);
}
}
}
1、检查表空否
2、遍历查找,先锁定一个数据元素,再遍历之后的数据元素是否有和锁定的数据元素重复,若重复则根据下标删除重复的数据元素
3、若是照上述编写程序,基本上能实现删除表中有重复的数据,但存在一个bug,如果重复的数据是连续2个以上且在表的末尾,则无法全部删除。结果如下:
60 60 30 60 80 60 60 60 30 80 60 test: 60 60 30 60 80 60 60 i=0 j=1 60 30 60 80 60 60 i=0 j=2 60 30 80 60 60 i=0 j=3 60 30 80 60 i=1 j=2 60 30 80 60 i=1 j=3 60 30 80 60 i=2 j=3 60 30 80 60
测试发现,第9~12行,由于删除重复元素后该元素后面的待遍历元素会往前移一位,而 j++又让待遍历元素下标往后移了一位,若遇上述情况,则导致恰巧错失比较了一个重复元素。因此在每次删除完重复数据后,将 j 回置1位并判断此时的元素是否与锁定元素相同,若相同则立即删除它。这只是一种情况,实际上还有多种,每种解决的方法又不同。。。
4、此问题有待解决。
遍历(打印)
void printList(LIST *list)
{
int i;
for(i=0;i<=list->last;i++)
printf("%d ",list->data[i]);
putchar(10);
}
从第一项开始循序往后访问直到最后一项
根据给定数据直接修改更新数据
void updataByData(LIST *list,INT data,INT val)
{
int i;
for(i=0;i<=list->last;i++)
{
if(data == list->data[i])
list->data[i] = val;
}
}
遍历寻找需要修改的数据并赋值覆盖
根据给定下标位置来修改更新数据
void updataByIndex(LIST *list,int position,INT val)
{
if(position>=0 && position<=list->last)
list->data[position] = val;
}
先判断给出位置是否合法,若合法直接通过下标修改数据
查找表中是否有某一数据
int referByDate(LIST *list,INT data)
{
int i;
for(i=0;i<=list->last;i++)
{
if(list->data[i] == data)
return 1;
}
return 0;
}
遍历的过程,加入判断条件
查找表中某一数据的位置
void findPos(LIST *list,INT data)
{
int i,flag = 1;
for(i=0;i<=list->last;i++)
{
if(data == list->data[i])
{
printf("%d ",i);
flag = 0;
}
}
if(flag)printf("%d",-1);
putchar(10);
}
遍历的过程,加入判断条件
合并两个顺序表
void combineList(LIST *li1,LIST *li2)
{
int i;
for(i=0; i<=li2->last; i++)
{
if(!referByDate(li1,li2->data[i]))
tailInsert(li1,li2->data[i]);
}
}
从表2中将表1中没有的数据插入到表1中
遍历表2,判断遍历的每一个数据在表1中是否存在,若不存在,则在表1中尾部插入
对表中数据顺序排序
void sortList(LIST *list)
{
int i,j,flag,temp;
for(i=0;i<list->last;i++)
{
flag = i;
for(j=i+1;j<=list->last;j++)
{
if(list->data[j] < list->data[flag])
flag = j;
}
temp = list->data[i];
list->data[i] = list->data[flag];
list->data[flag] = temp;
}
}
选择排序
示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TEST 1
#define N 100
typedef int INT;
typedef struct sequenList{//数据
//数据项
INT data[N];
int last;//数组data的最后一个数据的下标
int lenth;//数组的大小
}LIST;
LIST *creat();
int isEnpty(LIST *list);
int isFull(LIST *list);
void tailInsert(LIST *list,INT val);
void insert(LIST *list,int position,INT val);
void printList(LIST *list);
void deletList(LIST *list);
void updataByData(LIST *list,INT data,INT val);
void updataByIndex(LIST *list,int position,INT val);
void referByIndex(LIST *list,INT data);
void findPos(LIST *list,INT data);
void deletBypos(LIST *list,int position);
void deletRepetitionData(LIST *list,INT data);
void combineList(LIST *li1,LIST *li2);
void sortList(LIST *list);
int main(int argc, const char *argv[])
{
LIST *list = creat();//list:数据元素
LIST *list1 = creat();
#if TEST
printf("%d\n",sizeof(LIST));
tailInsert(list,60);
tailInsert(list,20);
tailInsert(list,30);
printList(list);//60 20 30
deletList(list);
printList(list);//60 20
tailInsert(list,30);
tailInsert(list,20);
printList(list);//60 20 30 20
updataByData(list,20,60);
tailInsert(list,60);
printList(list);//60 60 30 60 60
//updataByIndex(list,2,60);
updataByIndex(list,2,80);
printList(list);//60 60 80 60 60
findPos(list,60);//0 1 3 4
insert(list,1,30);
printList(list);//60 30 60 80 60 60
tailInsert(list,70);
printList(list);//60 30 60 80 60 60 70
deletBypos(list,6);
printList(list);//60 30 60 80 60
insert(list,1,60);
printList(list);//60 60 30 60 80 60
tailInsert(list,60);
printList(list);//60 60 30 60 80 60
deletRepetitionData(list,60);
printList(list);
tailInsert(list1,99);
tailInsert(list1,88);
tailInsert(list1,80);
tailInsert(list1,22);
tailInsert(list1,66);
tailInsert(list1,50);
printf("list : ");
printList(list);
printf("list1: ");
printList(list1);
combineList(list,list1);
printf("combi: ");
printList(list);
printf("sort : ");
sortList(list);
printList(list);
#else
#endif
return 0;
}
//创建一个顺序表
LIST *creat()
{
LIST *list = (LIST *)malloc(sizeof(LIST));
memset(list->data,0,sizeof(INT)*N);
list->last = -1;
list->lenth = 0;
return list;
}
//顺序表判空
int isEnpty(LIST *list)
{
return list->lenth==0 ? 1 : 0;
}
//顺序表判满
int isFull(LIST *list)
{
if(list->lenth == N)
return 1;
else
return 0;
}
//尾插法
void tailInsert(LIST *list,INT val)
{
list->last++;
list->data[list->last] = val;
list->lenth++;
}
//在给定位置插入数据元素
void insert(LIST *list,int position,INT val)
{
int i;
if(isFull(list))
printf("表满\n");
if(position<0 && position>list->last)
{
printf("位置不合法\n");
}
else{
for(i=list->lenth;i>position;i--)
{
list->data[i] = list->data[i-1];
}
list->data[position] = val;
list->lenth++;
list->last++;
}
}
//遍历
void printList(LIST *list)
{
int i;
for(i=0;i<=list->last;i++)
printf("%d ",list->data[i]);
putchar(10);
}
//从尾部删除一个元素
void deletList(LIST *list)
{
if(isEnpty(list))
printf("空表\n");
else
{
INT *p = &(list->data[0]);
bzero(p+list->last,sizeof(INT));
list->last--;
list->lenth--;
}
}
//根据给定数据直接修改更新
void updataByData(LIST *list,INT data,INT val)
{
int i;
for(i=0;i<=list->last;i++)
{
if(data == list->data[i])
list->data[i] = val;
}
}
//查找表中是否有某一数据
int referByDate(LIST *list,INT data)
{
int i;
for(i=0;i<=list->last;i++)
{
if(list->data[i] == data)
return 1;
}
return 0;
}
//根据给定下标位置来修改更新数据
void updataByIndex(LIST *list,int position,INT val)
{
if(position>=0 && position<=list->last)
list->data[position] = val;
}
//查找表中某一数据的位置
void findPos(LIST *list,INT data)
{
int i,flag = 1;
for(i=0;i<=list->last;i++)
{
if(data == list->data[i])
{
printf("%d ",i);
flag = 0;
}
}
if(flag)printf("%d",-1);
putchar(10);
}
//按照位置删除数据
void deletBypos(LIST *list,int position)
{
int i;
if(isEnpty(list))
printf("表空");
if(position<=0 && position>list->last)
printf("位置不合法");
else{
for(i=position;i<list->last;i++)
{
list->data[i] = list->data[i+1];
}
if(position == list->last)
deletList(list);
list->last--;
list->lenth--;
}
}
//删除表中有重复的数据,只留一个
void deletRepetitionData(LIST *list,INT data)
{
int i,j;
if(isEnpty(list))
printf("表空\n");
else{
for(i=0;i<list->last;i++)
{
for(j=i+1;j<=list->last;j++)
{
if(list->data[i]==list->data[j])
deletBypos(list,j);
//printf("i=%d j=%d\n",i,j);//test
//printList(list);//test
}
if(list->data[i] == list->data[--j])
//deletBypos(list,j);
deletList(list);
}
}
}
//将两个表合并
void combineList(LIST *li1,LIST *li2)
{
int i;
for(i=0; i<=li2->last; i++)
{
if(!referByDate(li1,li2->data[i]))
tailInsert(li1,li2->data[i]);
}
}
//对表中数据顺序排序
void sortList(LIST *list)
{
int i,j,flag,temp;
for(i=0;i<list->last;i++)
{
flag = i;
for(j=i+1;j<=list->last;j++)
{
if(list->data[j] < list->data[flag])
flag = j;
}
temp = list->data[i];
list->data[i] = list->data[flag];
list->data[flag] = temp;
}
}
结果
408
60 20 30
60 20
60 20 30 20
60 60 30 60 60
60 60 80 60 60
0 1 3 4
60 30 60 80 60 60
60 30 60 80 60 60 70
60 30 60 80 60
60 60 30 60 80 60
60 60 30 60 80 60 60
60 30 80
list : 60 30 80
list1: 99 88 80 22 66 50
combi: 60 30 80 99 88 22 66 50
sort : 22 30 50 60 66 80 88 99
本文链接:https://shengto.top/data_structure/135.html
转载时须注明出处及本声明