线性表是计算机程序设计活动中最经常遇到的一种操作对象,也是数据结构中最简单,最基本和最重要的结构形式之一。实际上,线性表在很多领域,尤其是在程序设计语言和程序设计过程中大量使用,并非一个陌生的概念。本文将从以下几个方面介绍线性表(不是线性链表):
1. 线性表定义
2. 线性表基本操作实现
3. 线性表特点及优缺点
1、线性表定义
线性表是最基本、最简单、也是最常用的一种数据结构。
线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。
我们说“线性”和“非线性”,只在逻辑层次上讨论,而不考虑存储层次,所以双向链表和循环链表依旧是线性表。
在数据结构逻辑层次上细分,线性表可分为一般线性表和受限线性表。一般线性表也就是我们通常所说的“线性表”,可以自由的删除或添加结点。受限线性表主要包括栈和队列,受限表示对结点的操作受限制。
线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构。 —–来自百度百科
2、线性表基本操作
主要有以下几个操作
- 在长度为n的线性表data的第i个位置插入一个新的数据元素item
- 打印长度为n的线性表data中的所有元素
- 删除长度为n的线性表data中的第i个数据元素
- 确定元素item在长度为n的线性表data中的位置
- 删除重复的元素
- 排序
下面是main.c文件
#include "LinearStorage.h"
int main()
{
int i,j,k;
int data[100];
int length=6;
int l;
data[0]=1;
data[1]=2;
data[2]=3;
data[3]=4;
data[4]=3;
data[5]=2;
printData(data,length);
addItem(data,&length,2,7);
printf("插入后:\n");
printData(data,length);
deleteItem(data,&length,3);
printf("删除第三个元素后:\n");
printData(data,length);
locate(data,2,length);
purge(data,&length);
printf("去重后:");
printData(data,length);
bubbleSort(data,length);
printf("排序后:\n");
printData(data,length);
return 0;
}
下面是LinearStorage.h文件
#ifndef LINEARSTORAGE_H_INCLUDED
#define LINEARSTORAGE_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MaxSize 100
void addItem(int data[],int *length,int i,int item);
void deleteItem(int data[],int *length,int iDelete);
int locate(int data[],int item,int length);
void purge(int data[],int *length);
int locate(int data[],int item,int length){
int i;
for(i=0;i<length;i++){
if(data[i]==item){
printf("查找:2是第%d个元素\n",i+1);
return i+1;
}
}
return -1;
}
void addItem(int data[],int *length,int i,int item){
//向数组中第i个位置插入数据item
/*length表示长度,函数声明*length,调用函数的要加&*/
int m;
if(i<1||*length==MaxSize||i>*length+1){
printf("插入不符合要求");
}
else{
for(m=*length-1;m>=i-1;m--)
{//从后往前,每个元素位置往后移动一位
data[m+1]=data[m];
}
data[i-1]=item;
(*length)++;//数组长度加一
}
}
void deleteItem(int data[],int *length,int iDelete){
int i;
if(iDelete>*length||iDelete<1)
printf("删除操作不符合要求");
else
{
for(i=iDelete;i<*length;i++){
data[i-1]=data[i];
}
(*length)--;
}
}
void purge(int data[],int *length)//去除重复的元素
{
int i,j,k;
for(i=0;i<*length;i++){
for(j=i+1;j<*length;j++){
if(data[j]==data[i]){
/*理论上下面这个for循环进行的操作就是deleteItem()函数进行的操作,但是换成deleteItem(data,&length,j+1);总是出错,只好又写一遍删除操作*/
for(k = j+1; k<*length; k ++)//依次前移一位。
data[k-1] = data[k];
(*length)--;//总长度减一。
j--;
//for循环中j自动+1,但是如果去掉重复后,表的长度-1,j也要减一
}
}
}
/*
// 这是第二种写法,使用while循环写的
int i=0,j,k;
while(i<*length-1){
j=i+1;
while(j<*length){
if(data[j]==data[i])
{
for(k = j+1; k<*length; k ++)//依次前移一位。
data[k-1] = data[k];
(*length)--;//总长度减一。
}
else
j++;
}
i++;
}
*/
}
void printData(int data[],int length){
int i;
printf("线性表中元素是:\n");
for(i=0;i<length;i++){
printf("%d ",data[i]);
}
printf("\n线性表长度是%d\n",length);
}
void bubbleSort(int data[],int length){
//冒泡排序
int i,j;
int temp;
for(i=0;i<length-1;i++){
for(j=0;j<length-1-i;j++){
if(data[j]>data[j+1]){
temp=data[j];
data[j]=data[j+1];
data[j+1]=temp;
}
}
}
}
#endif // LINEARSTORAGE_H_INCLUDED
运行结果:
3、 线性表特点及优缺点
*特点*
线性表的顺序存储结构的最大特点是逻辑上相邻的两个数据元素在屋里地址上也相邻,也正是因为这个特点使得线性表在顺序存储结构中有明显的优缺点。
*优点*
1. 构造原理简单直观,容易理解。
2. 若已知每个数据元素所占的存储单元个数,并且知道第一个元素的存储位置,则表中任意一个元素的位置可以通过一个简单的解析式计算出。
3. 可以随机存取表中任意一个数据元素,存取速度快,并且存取任意一个数据元素的时间代价相同。
4. 只需存放数据元素本身的信息,而无需其他额外空间开销,这一点是相对于链表来说的。
*缺点*
1. 需要一片连续的存储但愿作为线性表的存储空间
2. 存储空间需要事先分配
3. 进行插入或者删除操作时,需要现对插入或者删除位置后面的所有数据元素进行移动,操作的时间效率低,且插入或删除点的位置靠前时更是如此。
*总结*
综上,顺序存储结构比较适合用于线性表的长度不经常发生变化,或者只需要在顺序存取设备上批处理的场合。