【线性表的定义】
线性表:n个数据类型相同的有序元素a0,a1,a2,…,an-1组成的集合
n称为线性表的长度,n=0时称为空表
【线性表的数组实现】
线性表的顺序表示:用一维数组存储线性表
顺序表:顺序表示的线性表
缺点:恰当地预设数组大小是困难的
C语言结构定义:
typedef struct list{
int size,maxlist;
int Elements[MaxSize];
}List;
图示:
#include<stdio.h>
#define MaxSize 100 //顺序表的最大容量
/*
在下述定义的结构类型List中,
size是线性表的长度,
maxlist是表的最大允许长度,
一维数组Elements用以存放线性表中的元素。
*/
typedef struct list{
int size,maxlist; //size=0时,线性表为空
int Elements[MaxSize]; //线性表的容量maxlist可以由用户通过参数maxsize设定,其值不大于MaxSize
}List;
//创建空顺序表
void CreateList(List *lst,int maxsize)
{
lst->size=0;
lst->maxlist=maxsize;
}
//判空
int IsEmpty(List lst)
{
return lst.size==0;
}
//判满
int IsFull(List lst)
{
return lst.size==lst.maxlist;
}
//搜索
int Search(List lst,int x)
{
int i,pos,flag=0; //flag=0表示未找到x
for(i=0;i<lst.size;i++){ //顺序搜索顺序表中元素
if(lst.Elements[i]==x){
flag=1;
pos=i;
break; //退出搜索
}
}
if(flag==0){
return -1; //无x返回-1
}
else{
return pos; //有x返回其下标
}
}
//插入
void Insert(List *lst,int pos,int x)
{
int i;
if(IsFull(*lst)){
printf("顺序表满,无法插入!\n");
return; //什么都不做
}
for(i=lst->size;i>pos+1;i--){
lst->Elements[i]=lst->Elements[i-1]; //元素Elements[n-1],Elements[n-1],…,Elements[pos+1]依次后移
}
lst->Elements[pos+1]=x; //将x赋给Elements[pos+1]
lst->size++; //顺序表长度增1
}
//删除
void Delete(List *lst,int pos)
{
int i;
if(IsEmpty(*lst)){
printf("顺序表空,无法删除!\n");
return;
}
if(pos<0||pos>lst->size-1){ //如果下标超限
printf("顺序表中无此元素!\n");
return;
}
if(pos==lst->size-1){ //如果删除元素为表尾元素
lst->size--;
}
else{
for(i=pos;i<lst->size-1;i++){
lst->Elements[i]=lst->Elements[i+1]; //元素Elements[pos+1],Elements[pos+2],…,Elements[n-1]依次前移
}
lst->size--; //顺序表长度减1
}
}
//输出顺序表
void Display(List lst)
{
int i;
if(IsEmpty(lst)){
printf("顺序表空,无元素输出!\n");
return;
}
for(i=0;i<lst.size;i++){
printf("%d",lst.Elements[i]);
}
printf("\n");
}
int main()
{
List lst; //定义顺序表
int pos;
CreateList(&lst,10); //创建长度为10的空顺序表
Insert(&lst,-1,3); //3插入顺序表
Display(lst);
Insert(&lst,-1,1);
Display(lst);
pos=Search(lst,3); //搜索3的位置
Insert(&lst,pos,4);
Display(lst);
pos=Search(lst,4);
Delete(&lst,pos); //删除4
Display(lst);
return 0;
}
程序测试:
【线性表的链表实现】
链表:利用单链表来创建线性表
空链表的表示:head = NULL
优点:可随意改变表的长度
C语言结构定义:
#include<stdio.h>
typedef struct node{
int data;
struct node *next;
}Node;
typedef struct list{
Node *head;
}List;
实现代码:
#include<stdio.h>
#include<malloc.h>
typedef struct node{
int data;
struct node *next;
}Node;
typedef struct list{
Node *head;
}List;
//创建空链表
void CreateList(List *lst)
{
lst->head=NULL;
}
//判空
int IsEmpty(List lst)
{
return lst.head==NULL;
}
//判断当前位置是否是链表的末尾
int IsLast(List lst,Node *p)
{
return p->next==NULL;
}
//搜索x结点的地址
Node* Search(List lst,int x)
{
int flag=0;
Node *p=lst.head; //定义探测指针p并指向头结点
while(p!=NULL){
if(p->data==x){
flag=1; //找到值为x的结点
break;
}
p=p->next; //p后移
}
if(flag==0){
return NULL; //无此结点,返回空值
}
else{
return p; //有此结点,返回其地址
}
}
//插入
void Insert(List *lst,Node *pos_node,int x) //将要插入的元素x与表lst和位置pos_node一起传入
{ //将一个元素插入到由pos_node所指示的位置之后
Node *New_node; //新结点
New_node=(Node *)malloc(sizeof(Node)); //为新结点申请空间
New_node->data=x; //新结点的数据域赋值x
New_node->next=NULL; //新结点的指针域赋空值
if(IsEmpty(*lst)){ //如果链表为空
lst->head=New_node; //新结点作链头
}
else{
if(pos_node==NULL){ //如果插入位置结点为空值
New_node->next=lst->head; //新结点插入链头
lst->head=New_node;
}
else{
New_node->next=pos_node->next;
pos_node->next=New_node; //新结点插入pos_node之后,进入链表
}
}
}
//删除
void Delete(List *lst,int x)
{
Node *p,*TmpCell;
p=Search(*lst,x); //找出元素为x的结点的前驱结点P
if(!IsLast(*lst,p)){ //删除第一次出现的x,如果x不在表中则什么都不做
TmpCell=p->next;
p->next=TmpCell->next;
free(TmpCell);
}
}
//输出单链表
void Display(List lst)
{
Node *p=lst.head;
if(IsEmpty(lst)){
printf("链表为空,无结点输出!\n");
return;
}
while(p!=NULL){
printf("%d=>",p->data);//输出链表结点值
p=p->next; //p后移
}
printf("NULL");
printf("\n");
}
int main()
{
List lst; //定义链表
Node *pos_node;
CreateList(&lst); //创建空链表
Insert(&lst,NULL,3); //3插入顺序表
Display(lst);
Insert(&lst,NULL,1);
Display(lst);
pos_node=Search(lst,3);
Insert(&lst,pos_node,4);
Display(lst);
Delete(&lst,3); //删除第几个位置上的数
Display(lst);
return 0;
}
程序测试: