线性表
线性表是最简单也是最常用的一种线性结构,线性表实际上是基于前面元素和后面元素之间的一种相邻关系的结构
前言
线性表是由同一类型数据元素组成的有限序列。其中第一个元素无前驱结点,最后一个元素无后继结点,除第一个和最后一个元素其余元素均有一个前驱结点和直接后继结点。
一、线性表是什么?
示例:A = (a1,a2,a3,—ai,ai+1 ,----,an-1,an)
在A表中,a1为第一个数据元素,an为最后一个数据元素,ai在ai+1前面我们称ai是ai+1的前驱,ai+1在ai的后面我们称ai+1是ai的后继,除去开头数据元素没有前驱,末尾数据元素没有后继,其余数据元素都有对应的前驱和后继。
在线性表中元素的个数我们称为该表的长度,如果长度为0,则成为空表
二、线性表的顺序储存。
假设线性表中有n个元素,每个元素占k个存储单元,第一个元素的地址为Loc(a1),则第i个元素的地址Loc(ai):
Loc(ai) = Loc(a1) + (i-1) * k;
其中Loc(a1)称为基地址。
三、线性表的基本操作(增,删,改,查)
定义线性表
#define ListSize 100 //线性表的最大长度
typedef int DataType;
typedef struct
{
DataType data[ListSize]; //用数组存储线性表中的元素
DataType length; //顺序表中元素的个数
}SeqList, *PSeqList;
初始化线性表
void InitList(PSeqList L)
{
if (L == NULL)
{
return;
}
L->length = 0;
}
求顺序表的长度
int LengthList(PSeqList L)
{
if (L == NULL)
{
return 0;
}
return L->length;
}
在顺序表中加入元素
int InsList(PSeqList L, int i, DataType e)
{
//判断插入位置是否合法
if (i < 1 || L->length >(LengthList(L) + 1))
{
printf("插入位置不合法!\n");
return 0;
}
//判断顺序表是否已满
else if (L->length >= ListSize)
{
printf("顺序表已满,不能插入!\n");
return 0;
}
else
{
for (k = i; k <= L->length; k--)
{
L->data[k + 1] = L->data[k];
}
L->data[i - 1] = e;
L->length++; //数据表的长度加1
return 1;
}
return 0;
}
头插
头插,即在表头插入元素e,在表头插入元素,需要将表中的元素依次后移一位,然后将要插入的元素e赋给数字的首元素,执行插入操作后将表长L->length++;需要注意的是移动元素要从顺序表的最后一个元素开始移动,如果从第1个元素开始移动,会使得第1个元素的值覆盖第2个元素的值,然后把第二个元素后移则会使第2个元素的值(原来第1个元素值)覆盖第3个元素的值,依次类推,最后出插入元素外,其余元素值均为原顺序表中第一个元素的值。
void PushFront(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("顺序表已满,不能插入!\n");
}
//将表中元素依次后移一位
for (k = L->length; k > 0; k--)
{
L->data[k] = L->data[k - 1];
}
//插入元素
L->data[0] = e;
L->length++;
}
尾插
在顺序表表尾插入元素e,L->data[L->length] = e;将元素e的值赋给顺序表中最后一个元素的下一个元素;尾插操作,需要判断顺序表是否已满,尾插后将顺序表长度L->length++;
void PushBack(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("顺序表已满,不能插入!\n");
}
L->data[L->length] = e;
L->length++;
}
在顺序表中查找元素
int Locate(PSeqList L, DataType e)
{
for (k = 0; k < L->length; k++)
{
if (L->data[k] == e)
{
//k为e对应的数组下标,在表中对应序号应为k+1
return k + 1;
}
}
return 0;
}
总代码
头函数,声明
#pragma once
#define ListSize 100 //线性表的最大长度
typedef int DataType;
typedef struct
{
DataType data[ListSize]; //用数组存储线性表中的元素
DataType length; //顺序表的长度
}SeqList, *PSeqList;
void InitList(PSeqList L); //顺序表的初始化操作
int LengthList(PSeqList L); //求顺序表的长度
int GetData(PSeqList L, int i); //返回数据表中第i个元素的值
int InsList(PSeqList L, int i, DataType e); //在顺序表的第i个位置插入元素
int DelList(PSeqList L, DataType i, DataType* e); //删除顺序表L的第i个数据元素
int Locate(PSeqList L, DataType e); //查找数据元素e在表中的位置
void PushFront(PSeqList L, DataType e); //头插,在表头插入元素e
void PopFront(PSeqList L); //头删,删除表中的第一个元素
void PushBack(PSeqList L, DataType e); //尾插,在表尾插入元素e
void PopBack(PSeqList L); //尾删,删除表尾元素
void ClearList(PSeqList L); //清空顺序表
int EmptyList(PSeqList L); //判断顺序表是否为空
void PrintList(PSeqList L); //打印表中元素
函数
#include <stdio.h>
#include "SeqList.h"
int k = 0; //全局变量,用于作部分操作的循环变量
//初始化顺序表
void InitList(PSeqList L)
{
if (L == NULL)
{
return;
}
L->length = 0;
}
//求顺序表的长度
int LengthList(PSeqList L)
{
if (L == NULL)
{
return 0;
}
return L->length;
}
//返回数据表中第i个元素的值
int GetData(PSeqList L, int i)
{
if (L->length < 1 || (L->length > LengthList(L)))
{
return 0;
}
//数据元素的序号从1开始,数组下表从0开始,第i个元素对应的数组下标为i-1;
return L->data[i - 1];
}
//在L中第i个位置,插入新的数据元素e
int InsList(PSeqList L, int i, DataType e)
{
//判断插入位置是否合法
if (i < 1 || L->length >(LengthList(L) + 1))
{
printf("插入位置不合法!\n");
return 0;
}
//判断顺序表是否已满
else if (L->length >= ListSize)
{
printf("顺序表已满,不能插入!\n");
return 0;
}
else
{
for (k = i; k <= L->length; k--)
{
L->data[k + 1] = L->data[k];
}
L->data[i - 1] = e;
L->length++; //数据表的长度加1
return 1;
}
return 0;
}
//删除L的第i个数据元素
int DelList(PSeqList L, DataType i, DataType* e)
{
if (L->length < 1)
{
printf("表为空!\n");
return 0;
}
*e = L->data[i - 1];
for (k = i; k < L->length; k++)
{
L->data[k - 1] = L->data[k];
}
L->length--;
return *e;
}
//查找e在表中的位置
int Locate(PSeqList L, DataType e)
{
for (k = 0; k < L->length; k++)
{
if (L->data[k] == e)
{
//k为e对应的数组下标,在表中对应序号应为k+1
return k + 1;
}
}
return 0;
}
//头插,在表头插入元素e
void PushFront(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("顺序表已满,不能插入!\n");
}
//将表中元素依次后移一位
for (k = L->length; k > 0; k--)
{
L->data[k] = L->data[k - 1];
}
//插入元素
L->data[0] = e;
L->length++;
}
//头删,删除顺序表中的第一个元素,把顺序表中的元素依次往前移动一位
void PopFront(PSeqList L)
{
if (EmptyList(L))
{
printf("顺序表为空,不能插入!\n");
}
for (k = 1; k <= L->length - 1; k++)
{
L->data[k - 1] = L->data[k];
}
L->length--;
}
//尾插
void PushBack(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("顺序表已满,不能插入!\n");
}
L->data[L->length] = e;
L->length++;
}
//尾删
void PopBack(PSeqList L)
{
if (EmptyList(L))
{
printf("表为空!\n");
}
L->length--;
}
//清空顺序表
void ClearList(PSeqList L)
{
L->length = 0;
}
//判断表是否为空
int EmptyList(PSeqList L)
{
if (L->length == 0)
{
return 1;
}
return 0;
}
//打印表中元素
void PrintList(PSeqList L)
{
if (EmptyList(L))
{
printf("表为空!\n");
return;
}
for (k = 0; k < L->length; k++)
{
printf("%-3d", L->data[k]);
}
printf("\n");
}
附加
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
struct Course {
int code; //课程编号
char *name;//课程名称
int weight;//课程权重
};
struct Course *date;
int length;
int curlen=0;
void initList();
int insertCourse(struct Course crs);
struct Course *deleteCourse(int i);
void findCourse(char *clsname);
void printList();
int main()
{
struct Course c1,c2,c3,c4,c5,c6,c7,c8,c9,c10;
//初始化顺序表
initList();
//插入课程编号
c1.code=1;
c1.name="程序设计";
c1.weight=9;
insertCourse(c1);
c2.code=8;
c2.name="操作系统";
c2.weight=6;
insertCourse(c2);
c3.code=10;
c3.name="线性代数";
c3.weight=5;
insertCourse(c3);
c4.code=5;
c4.name="计算机算法";
c4.weight=7;
insertCourse(c4);
c5.code=2;
c5.name="离散数学";
c5.weight=2;
insertCourse(c5);
c6.code=7;
c6.name="编译原理";
c6.weight=4;
insertCourse(c6);
c7.code=3;
c7.name="数据结构";
c7.weight=8;
insertCourse(c7);
c8.code=6;
c8.name="微机原理";
c8.weight=3;
insertCourse(c8);
c9.code=4;
c9.name="汇编语言";
c9.weight=1;
insertCourse(c9);
c10.code=9;
c10.name="高等数学";
c10.weight=5;
insertCourse(c10);
//输出插入结果
printList();
printf("\n");
//根据课程名称查找课程,如查找高等数学
findCourse("高等数学");
printf("\n");
//删除第二个课程
*deleteCourse(5);
printf("\n");
//输出
printList();
return 0;
}
//初始化
void initList()
{
length=30;
curlen=0;
date=(struct Course *)malloc(sizeof(struct Course)*length);
}
//按照课程编号有序插入新数据元素crs
int insertCourse(struct Course crs)
{
int i=0;int n;
if(curlen >= length)
return 0;
for(;i<curlen;i++)
{
if(date[i].code>crs.code)
break;
}
if(i<curlen){
for(n=curlen-1;n>=i;n--)
{
date[n+1]=date[n];
}
}
date[i] = crs;
curlen++;
return 1;
}
//删除课程
struct Course*deleteCourse(int i){
struct Course crs;int n;
//删除位置判断
if(i<1||i>curlen){
printf("删除位置有误!\n");
return NULL;
}
//保存删除前第i个数据元素
crs = date[i-1];
//从第i+1个位置开始依次向前移一个
for(n=i;n<curlen;n++)
{
date[n-1]=date[n];
}
curlen--;
return &crs;
};
//根据课程名称查找课程
void findCourse(char *clsname){
struct Course *crs = NULL;
int i;
for(i=0;i<curlen;i++){
if(strcmp(date[i].name,clsname)==0)
crs = &date[i];
}
if(crs!=NULL){
printf("code name weight \n",crs->code,crs->name,crs->weight);
printf("%d %s %d\n",crs->code,crs->name,crs->weight);
}
else
printf("当前未找到 %s\n",clsname);
}
//打印列表信息
void printList(){
int i;
printf("code name weight \n");
for(i=0;i<curlen;i++){
printf("%d %s %d\n",date[i].code,date[i].name,date[i].weight);
}
}