1.定义
什么是顺序表
顺表是一种线性结构,它使用一段连续的物理地址存储单元来存储数据元素,并一般采用数组的形式进行存储和操作。顺序表可以轻松地进行数据的插入、删除、查找和修改操作。通过使用数组实现,顺序表充分利用了数组的随机访问特性,使得操作效率较高。顺序表的操作主要涉及到对数组的插入和删除操作时,需要移动元素的位置,以保持顺序表的连续性。此外,顺序表的长度可以动态调整,可以根据实际需求进行扩容或缩容。
2.顺序表的特点:
1.顺序,并且连续,访问方便;
2.大小固定;
3.表满不能存,表空不能取
根据顺序表的特点,可以体现出顺序表的优缺点:
优点:访问方便
缺点:插入、删除不方便,需要移动元素。
常见的线性表基本运算( ):
- InitList(L):构造一个空的线性表L,即表的初始化。
- ListLength(L):求线性表L中的节点个数,即求表长。
- GetNode(L,i):求线性表第i个节点,1<=i<=ListLength(L)
- LocateNode(L,x):在L中查找值为x的结点,并返回x在L中的位置。若L中没结点的值为x,则返回一个特殊值表示查找失败。
- InsertList(L,x,i):在表L的第i个位置上插入一个值x的结点。
- DeleteList(L,i):删除线性表L的第i个结点.
顺序表的类型定义:
typedef struct
{
int data[ListSize]; //数组data用于存放表节点,ListSize表示数组大小
int length; //表示当前表长度
}SeqList; //结构体类型
注意:线性表元素的逻辑序号是从1开始的,而对应顺序表的data[]数组下标是从0开始的(物理序号)
地址的计算方法:
假设线性表中所有结点类型相同,每个结点占用存储空间大小亦相同。假设每个结点占用c个存储单元,其中第一个单元的存储地址则是该结点的存储地址,并设开始结点a1的存储地址是 LOC(a1),那么结点a i的存储地址LOC(a i)可通过下式计算:
LOC(ai)=LOC(a1)+(i-1)*c (1≤i≤n)
例如:已知LOC(a1)为100,每个结点占用4个存储单元,LOC(a4)为112。具
体描述如图所示。
3.顺序表基本运算:
1.插入:
线性表的插入运算是指在表的第i(1<=i<=n+1)个位置上,插入一个新节点x,使长度为n的线性表变成长度为n+1的线性表。
顺序表插入操作过程:将表中位置为n上的结点,依次后移到位置n+1上,空出第个位置,然后在该位置上插入新结点x。仅当插入位置i=n+1时,才无须移动结点,直接将x插入表的末尾。
具体算法描述如下:
void InsertList(SeqList *L, DataType x, int i)
{//将新结点x插入L所指的顺序表的第i个结点a的位置上
int j;
if(i<1||li>L->length+1)
Error("position error"); //非法位置退出运行
if(L->length>=ListSize)
Error("overflow"); //表空间溢出退出运行
for(j=L->length-1;j>=i-1;j--)
L->data[j+1]=L->data[j]; //节点后移
L->data[i-1]=x; //插入X
L->length++; //表长+1
}
用尾插法建立带头节点的单链表算法如下:
LinkList CreatList()
{
char ch;
ListNode *head=(ListNode *)malloc(sizeof(ListNode);//生成头节点
ListNode *s,*r; //工作指针
r=head; //尾指针初值也指向头结点
while(ch=-getchar0)!=\n')
{
s=(ListNode*)malloc(sizeof(ListNode));//生成新结点,第①步
s->data=ch; //将读入的数据放入新结点的数据域中,第②步
r->next=s;//第③步
r=s; //第④步
}
r->next-NULL; //终端结点的指针域置空,或空表的头结点指针域置空
return head;
}
插入运算:
插入运算是将值为x的新结点插入到表的第i个结点的位置上,即插入到ar1与a;之间。
步骤:①找到ai1存储位置po
②生成一个数据域为x的新结点s。
③新结点的指针域指向结点 aio
④ 令结点p的指针域指向新结点。
插入过程如图所示。
2.删除:
线性表的删除运算是指将表的第i(1≤i≤n)个结点删去,使长度为n的线性表变成长度为n-1的线性表。
顺序表删除操作过程:若i一n,则只要简单地删除终端结点,无须移动结点;若l≤i≤n-1,则必须将表中位置i1,i+2,…,n的结点,依次前移到位置i,i1,……,n-1上,覆盖前一个结点,相当于删除第i个结点。
具体算法描述如下:
void DeleteList(SeqList *L,int i)
{/从L所指的顺序表中删除第i个结点aj
int j;
if(i<1||i>L->length)
Error("position error");//非法位置
for(j=i;j<=L->length-l;j++)
L->data[j-1]-L->data[j];//结点前移
L->length--; //表长减小
}
3.删除运算
删除运算是将表的第i个结点删去。步骤:
①找到a(i-1)的存储位置p.
②让r指向ai,方便释放。
③令p->next 指向ai的直接后继结点,跨过ai结点。
④通过执行 free(r)释放节点ai的空间,节省内存空间。
删除过程如图所示。
4.修改
【代码思路】: 要实现修改数据,我们只需要先判断输入下标是否合法。在将对应下标数据进行修改即可。
void SLModify(SL* ps, int pos, SLDateType x)
{
assert(ps);
assert(pos >= 0 && pos < ps->size);
ps->a[pos] = x;
}
演示1:
代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 1000
/*顺序表的定义*/
typedef struct list
{
int data[MAXSIZE]; /*存储空间,数组*/
int length; /*顺序表的长度*/
}SeqList;
int main(int argc, char* argv[])
{
SeqList L; /* 声明了一个顺序表L */
int i, j, k;
int x;
/*初始化*/
L.length = 0;
printf("顺序表L初始化完成。\n");
printf("1. 插入5个元素\n");
/*插入一些元素, 采用尾插法,新插入元素放在最后*/
for(i=0;i<5;i++)
{
printf("\t[%d].", i+1);
scanf("%d", &x);
/*尾插法*/
L.data[L.length] = x;
L.length++;
}
printf("输出顺序表L\n");
for(i=0;i<L.length;i++)
{
printf("L(%d) = %d\n", i+1, L.data[i]);
}
printf("2. 在指定位置插入元素x\n");
printf("请输入位置k:");
scanf("%d", &k);
printf("请输入元素x:");
scanf("%d", &x);
printf("正在检查位置k合法性...\n");
if(k<1 || k>L.length+1)
{
printf("位置k不合法!\n");
return 0;
}
printf("位置k检查结束,插入元素【%d】...\n", x);
j=0;
for(i=L.length;i>=k;i--)
{
j++;
L.data[i] = L.data[i-1];
}
printf(" 移动元素%d个\n", j);
L.data[i] = x;
L.length++;
printf("输出新的顺序表L\n");
for(i=0;i<L.length;i++)
{
printf("L(%d) = %d\n", i+1, L.data[i]);
}
printf("删除顺序表L第k个元素\n");
printf("请输入位置k:");
scanf("%d", &k);
printf("正在检查位置k合法性...\n");
if(k<1 || k>L.length)
{
printf("位置k不合法!\n");
return 0;
}
printf("位置k检查结束,开始删除...\n");
/*移动元素*/
for(i=k;i<L.length;i++)
{
L.data[i-1] = L.data[i];
}
L.length--;
printf("输出新的顺序表L\n");
for(i=0;i<L.length;i++)
{
printf("L(%d) = %d\n", i+1, L.data[i]);
}
system("pause");
return 0;
}
演示2:
代码如下:
#include <stdio.h>
#include "SeqList.h"
#include "welcom.h"
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
SeqList L;
int cmd;
int i;
int m,n;
DataType x;
for(i=0;i<strlen(welcome);i++)
{
printf("%c",welcome[i]);
for(m=0;m<10000;m++)
for(n=0;n<1000;n++)
{
;
}
}
printf("\n\n\n");
printf("-----------顺序表演示程序----------\n");
do
{
printf("1. 初始化顺序表\n");
printf("2. 插入元素\n");
printf("3. 删除元素\n");
printf("4. 判断顺序表是否为空\n");
printf("5. 判断顺序表是否满\n");
printf("6. 输出顺序表\n");
printf("10. 帮助\n");
printf("0. 退出\n");
printf("请输入您要进行的操作(1~6,0退出):");
scanf("%d", &cmd);
switch(cmd)
{
case 1:
if(!init(&L))
{
printf("顺序表已初始化!\n");
}
break;
case 2:
printf("请输入位置i,插入元素x(i,x):");
scanf("%d,%d",&i,&x);
if(!insert(&L,i,x))
{
printf("元素(%d)已插入位置[%d]\n",x, i);
}
break;
case 5:
if(full(&L))
{
printf("顺序表已满!\n");
}
else
{
printf("顺序表未满!\n");
}
case 6:
print(&L);
break;
case 10:
printf(" 本程序为顺序表的演示程序,有XXX设计开发,程序完成了。。。。功能!。。。\n");
break;
}
}while(cmd != 0);
system("pause");
return 0;
}
2.SeqList.c
目录
3.SeqList.h
/*
SeqList.h 顺序表定义
*/
#define MAXSIZE 1000
typedef int DataType;
/*顺序表*/
typedef struct
{
DataType data[MAXSIZE];
int length;
}SeqList;
/*顺序表初始化*/
int init(SeqList *L);
/*顺序表的长度*/
int length(SeqList *L);
/*顺序表是否满*/
int full(SeqList *L);
/*是否空*/
int empty(SeqList *L);
/*插入元素*/
int insert(SeqList *L, int i, DataType x);
/*删除元素*/
int delete1(SeqList *L, int i, DataType *x);
/*输出顺序表*/
void print(SeqList *L);
4.welcom.h
char welcome[] = "\
/\ \
( *)======/\==== \
)( / \ \
__________/ ) / \ \
\___ / / \"\" \ \
\____ _/ / (**) \ \
/ \__/ (----------) \
/____|__//_ ( 送给您- ) \
| ( 亲爱的 ) \
| ( )\
| (____)\
_|__\
\\ ☆新年 . 快乐☆";
作者声明:
以上内容作用于作业,内容质量仅供参考。文章代码纯手搓,参考自数据结构(C语言版)