数据结构与算法(2)— 一般线性表
(mi6236)
1、线性表定义
具有相同数据类型元素的一个有限序列。其基本特征为在一个非空线性结构中,有且只有一个称为第一个的元素;有且只有一个称为最后一个的元素。第一个元素无前驱,最后一个元素无后继,其余每个元素均有唯一前驱和唯一后继。
线性表是一种线性结构,任何一种线性结构都可以用线性表的形式表示。
2、线性表的顺序存储结构
线性表的顺序存储结构采用一组连续的存储单元依次存储线性表中的个数据元素。建立一个数组V,线性表的长度为N,V[ i ]表示第i个分量,第i个分量是线性表中的第i个元素ai在计算机存储器中的映像,即V[i]=ai。若线性表的第i个元素的存储地址为LOC(a1),每个元素用L个存储单元,则表的第i个元素的存储地址为LOC(ai)=LOC(a1)+(i-1)*L。
线性表的顺序表C语言描述:
#include <stdio.h>
#include <iostream.h>
#define MAXSIZE 10 /*顺序表的长度为对MAXSIZE的定义的值*/
typedef int elemtype;
typedef struct{
elemtype data[MAXSIZE+1];
int len;/*线性表数据的个数*/
}sqlist;
3、顺序表算法描述
注:为使算法清晰描述,数组下标按从1开始考虑,0位置元素空置。
一下程序在VC6.0中测试通过。
3.1、置一个线性表为空
void SetNull(sqlist *L)
{
L->len=0;
}
3.2、求线性表的长度
int GetLength(sqlist L)
{
return L.len;
}
1.3、读取线性表中的第i个元素
elemtype GetElem(sqlist L,int i)
{
if (i<=L.len)
return L.data[i];
else
{
printf("下标超限");
return 0;
}
}
3.4、修改或重写线性表中的第i个元素
void ReplaceElem(sqlist *L,int i,elemtype x)
{
L->data[i]=x;
}
3.5、向线性表中第i个元素之前插入一个新元素。
算法步骤:
3.5.1、检查线性表的存储空间是否已被占满,若占满,进行溢出处理。
3.5.2、检查i值是否超出所允许的范围(1<=i<=n+1,注意当i=n+1,表示在表尾进行插入,即把新元素插到最后一个元素的后面),若超出,进行超出范围处理。
3.5.3、将线性表的第i个元素和他后面的所有元素均后移一个位置。
3.5.4、将新元素写入到空出的位置(即第i个单元)上。
3.5.5、使线性表的长度加1.
int insert(sqlist *L,int i,elemtype x)
{
if (L->len>=MAXSIZE )
{
printf("overflow/n");
return 0;
}
if((i<1)||(i>(L->len+1)))
{
printf("插入下标越界/n");
return 0;
}
else
{
for(int j=L->len;j>=i;j--)
L->data[j+1]=L->data[j];
L->data[i]=x;
(L->len)++;
return 1;
}
}
此算法的时间复杂度为O(n)
3.6、向一个有序表中插入一个新元素,使得插入后仍然有序。
算法步骤:
3.6.1、检查线性表的存储空间是否已被占满,若占满,进行溢出处理。
3.6.2、将有序表中所有大于插入新元素的元素后移一个位置。
3.6.3、把新元素写入到空出的位置上。
3.6.4、线性表的长度加1。
int OrderInsert(sqlist *L,elemtype x)
{
if (L->len>= MAXSIZE )
{
printf("overflow/n");
return 0;
}
else
{
for(int i=L->len;i>0&&L->data[i]>=x;i--)
L->data[i+1]=L->data[i];
L->data[i+1]=x;
(L->len)++;
return 1;
}
}
此算法时间复杂度为O(n)。
3.7、删除线性表中的第i个元素
算法步骤:
3.7.1、检查i值是否超出所允许的范围(1<=i<=n+1,注意当i=n+1,表示在表尾进行插入,即把新元素插到最后一个元素的后面),若超出,进行超出范围处理。
3.7.2、把第i个元素赋给x;
3.7.3、把第i个元素后面的所有元素前移一个位置;
3.7.4、使线性表的长度减1.
elemtype del(sqlist *L,int i,elemtype x)
{
if((i<1)||(i>L->len+1))
{
printf("删除下标越界");
return 0;
}
else
{
x=L->data[i];
for(int j=i;j<=L->len;j++)
L->data[j]=L->data[j+1];
(L->len)--;
return x;
}
}
此算法时间复杂度为O(n)。
3.8、显示线性表中的所有元素
int ShowList(sqlist L)
{
if (L.len>=1)
{
for(int i=1;i<=L.len;i++)
printf("线性表第%d个元素为:%d/n",i,L.data[i]);
return 1;
}
else
{
printf("线性表中没有元素/n");
return 0;
}
}
3.9、测试程序
void main()
{
sqlist list; //声明一个线性表
elemtype elem;
char temp;
SetNull(&list); //置空线性表
printf("线性表中的元素个数为:%d 个/n",GetLength(list));
ShowList(list);
for (int i=1;i<=MAXSIZE;i++) //初始化线性表
{
elem=-1; //初始化元素为一个无效值
printf("线性表初始化,请输入一个值(输入q自动结束初始化):");
scanf("%d",&elem);
if (elem<0 || elem>32767)
{
temp=getchar();
break;
}
if (insert(&list,i,elem)==0)
break;
}
ShowList(list);
printf("线性表中的元素个数为:%d 个/n",GetLength(list));
printf("请键入要输出的线性表元素位置:"); /*读取线性表中的第i个元素*/
scanf("%d",&i);
printf("线性表中第%d个位置的值为:%d/n",i,GetElem(list,i));
printf("请键入要替换元素的位置:"); /*修改或重写线性表中的第i个元素*/
scanf("%d",&i);
printf("请输入替换后的值:");
scanf("%d",&elem);
ReplaceElem(&list,i,elem);
ShowList(list);
printf("请输入要插入元素的位置:");/*向线性表中第i个元素之前插入一个新元素。*/
scanf("%d",&i);
printf("请输入插入元素的值:");
scanf("%d",&elem);
insert(&list,i,elem);
ShowList(list);
printf("线性表中的元素个数为:%d 个/n",GetLength(list));
printf("请输入要删除元素的位置:");/*删除线性表中的第i个元素*/
scanf("%d",&i);
printf("被删除的元素值为:%d",del(&list,i,elem));
ShowList(list);
printf("线性表中的元素个数为:%d 个/n",GetLength(list));
sqlist OrderList; //初始化一个有序线性表
SetNull(&OrderList);
insert(&OrderList,1,2);
insert(&OrderList,2,8);
insert(&OrderList,3,20);
insert(&OrderList,4,99);
insert(&OrderList,5,230);
ShowList(OrderList);
printf("请输入要插入的元素:");
scanf("%d",&elem);
OrderInsert(&OrderList,elem);
ShowList(OrderList);
printf("线性表中的元素个数为:%d 个/n",GetLength(OrderList));
}