线性表: 是具有相同特性的数据元素组成的一个有限序列。
例如使用一个线性表来存取学生的学号,可表示成(1,2,3,4,5,6,7,8,9,10)
线性表的存储结构分为
顺序存储和
链式存储。
线性顺序存储
c/c++程序中的数组或字符串结构就是一种典型的线性表应用,特性是使用
连续的存储空间
来存储数据,在编译时就需要为相关变量分配内存,这种存储结构叫做顺序存储。
优点:只要确定存储空间里的起始位置,就能对表中任意元素进行随机存取。即查找效率高。
缺点:①
容易造成存储空间的浪费
②
因为在编译时就为相关变量分配内存,所以存储大小已经固定,要扩充容量时只能修改程序
③插入或删除效率低,因为存储空间是连续的,在数据量大的时候从头部插入数据,其后的所有数据都要往后面移动一个空间。存储空间有限,在执行插入操作时有溢出的危险。
顺序表的实现:(codeblocks完美运行)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h> //c语言中memset()函数的头文件
#define MAX 100 //该顺序表可以容纳100个数据
typedef struct seqlist
{
int length; //顺序表有效数据的长度
int date[MAX]; //用数组的形式实现顺序表
}seq;
//插入数据到顺序表中
int inser_seq(seq *head,int date)
{
//往顺序表中插入一个数据,尾部插入
if(head != NULL) //健壮性判断
{
if(head->length == MAX)
{
printf("线性表已满!\n");
return 0;
}
head->date[head->length] = date;
head->length++; //插入一个数据后,顺序表长度+1
return 1;
}
else
{
printf("链表为空!\n");
return 0;
}
}
//遍历顺序表中的数据
int display(seq *head)
{
if(head != NULL)
{
int i=0;
for(i=0;i<head->length;i++)
{
printf("date=%d\n",head->date[i]);
}
}
else
{
printf("链表为空!\n");
return 0;
}
}
//删除
int delete(seq *head,int val)
{
int i=0,j;
if(head != NULL)
{
//遍历顺序表
for(i=0;i<head->length;i++)
{
//找到要删除的数据
if(head->date[i] == val)
{
for(j=i;j<head->length-1;j++)
{
head->date[j]=head->date[j+1];//将删除位置后面的元素全部往前移动
}
head->length--; //删除一个数据后,顺序表长度-1
//防止数据连续的现象出现
i--;
}
}
return 1;
}
else
{
printf("链表为空!\n");
return 0;
}
}
//排序 (快速排序)
void quicksort(int *a,int low,int high)
{
if(low < high)
{
int key = a[low]; //将数组第一位最为健值
int left = low; //存储最小的下标
int right = high; //存储最大的下标
while(low < high)
{
while(low < high && a[high] >= key)//高位小于健值则交换
high--;
a[low] = a[high];
while(low < high && a[low] < key)//低位大于健值则交换
low++;
a[high] = a[low];
}
a[low] = key; //最后将基准值放入数组
quicksort(a,left,high-1); //遍历调用排序函数
quicksort(a,low+1,right);
}
}
//清空顺序表
void seqlist_clear(seq *seqlist)
{
if(seqlist == NULL)
return ;
memset(seqlist->date,0,MAX);//将数组内容全部赋0
seqlist->length = 0; //数组数据长度清0
return ;
}
//菜单
void menu()
{
system("cls");//清屏+
printf("\t\t|=============================================|\t\t\n");
printf("\t\t|==================顺序表操作=================|\t\t\n");
printf("\t\t|==================1.插入元素=================|\t\t\n");
printf("\t\t|==================2.打印链表=================|\t\t\n");
printf("\t\t|==================3.删除元素=================|\t\t\n");
printf("\t\t|==================4.排序链表=================|\t\t\n");
printf("\t\t|==================5.清空链表=================|\t\t\n");
printf("\t\t|=请输入对应的数字执行对应的功能!(输入0退出)=|\t\t\n");
printf("\t\t|====== 作者:RXX 时间:2017/07/04 ======|\t\t\n");
printf("\t\t|=============================================|\t\t\n");
}
int main()
{
//创建一个顺序表
seq *seqlist = (seq *)malloc(sizeof(seq));
seqlist->length =0;
//往顺序表中插入数据
int num;
int nub;
menu();
scanf("%d",&num);
while(num)
{
switch(num)
{
case 1:
{
printf("请输入要插入的元素\n");
scanf("%d",&nub);
if(inser_seq(seqlist,nub)==1)
{
printf("插入数据成功!按任意键回到菜单。\n");
}
//num=0;
break;
}
case 2:
{
int a = seqlist->length;
printf("顺序表长度: %d\n",a);
display(seqlist);
printf("打印完成!按任意键回到菜单。\n");
break;
}
case 3:
{
display(seqlist);
printf("请输入要删除的元素\n");
scanf("%d",&nub);
if(delete(seqlist,nub)==1)
{
printf("删除数据成功!按任意键回到菜单。\n");
}
//com=0;
else
{
printf("没有找到该元素!按任意键回到菜单。\n");
}
break;
}
case 4:
{
printf("排序后的链表:\n");
int a = seqlist->length;
printf("顺序表长度: %d\n",a);
quicksort(seqlist->date,0,seqlist->length-1);
display(seqlist);
printf("排序完成!按任意键回到菜单。\n");
break;
}
case 5:
{
seqlist_clear(seqlist);
printf("链表已清空!\n");
break;
}
}
getch(); //会等待你按下任意键,再继续执行下面的语句;
menu(); //执行完所选功能再次打印菜单
scanf("%d",&num);
}
printf("\t\t|==================感谢使用!再见!==================|\t\t\n");
return 0;
}
运行结果:
(1)运行菜单
(2)插入操作
(3)打印操作
(4)删除操作
(5)排序操作
(6)清空操作