线性表的应用

目录

目录

线性表基本操作

顺序存储

动态分配空间 

插入操作

删除操作

按值查找(顺序查找)

链式存储

单链表中结点类型描述

头插法建立单链表

尾插法建立单链表

按序号查找结点值

按值查找表结点

插入结点操作

删除结点操作

双链表

插入操作

删除操作

循环链表


线性表基本操作

InitList(&L):初始化表。构造一个空的线性表。

Length(L):求表长。返回线性表L的长度,即L中数据元素的个数。

LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。

GetElem(L,i):按位查找操作。获取表L中第 i 个位置的元素的值。

ListInsert(&L,i,e):插入操作。在表L中的第 i 个位置上 插入指定元素e。

ListDelete(&L,i,&e):删除操作。删除表L中第 i 个位置的元素,并用e返回删除元素的值。

PrintList(L):输出操作。按前后顺序输出线性表L的所有元素值。

Empty(L):判空操作。若L为空表,则返回true,否则返回false。

DestroyList(&L):销毁操作。销毁线性表,并释放线性表L所占用的内存空间。

顺序存储

线性表的顺序存储类型描述为:
线性表的元素类型为ElemType. 

1->静态分配 
#define Maxsize 50//定义线性表的最大长度
typedef struct{
    ElemType data[Maxsize];//顺序表的元素 
    int length;//顺序表的当前长度 
}SqList;//顺序表的类型定义 
2->动态分配
#define InitSize 100//表长度的初始定义
typedef struct{
    ElemType *data;//指示动态分配数组的指针
    int MaxSize,length;//数组的最大容量和当前个数 
}SeqList; //动态分配数组顺序表的类型定义

动态分配空间 

C的初始动态分配语句
L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);
C++的初始动态分配语句
L.data=new ElemType[InitSize];

插入操作

bool ListInsert(SqList &L,int i,ElemType e){//平均时间复杂度O(n)
	if(i<1||i>L.length+1)//判断i的范围是否有效 
	return false;
	if(L.length>=MaxSize)//当前存储空间已满,不能插入
	return false;
	for(int j=L.length;j>=i;j--)//将第i个元素及之后的元素后移 
	{
		L.data[j]=L.data[j-1]; 
	}
	L.data[i-1]=e;//在位置i处放入e
	L.length++;//线性表长度加1
	return true; 
}

删除操作

bool ListDelete(SqList &L,int i,ElemType &e){//平均时间复杂度O(n)
	if(i<1||i>L.length)//判断i的范围是否有效
	return false;
	e=L.data[i-1];//将被删除的元素赋值给e
	for(int j=i;j<L.length;j++)//将第i个位置后的元素前移 
		L.data[j-1]=L.data[j]; 
	L.length--;//线性表长度减1
	return true; 
} 

按值查找(顺序查找)

int LocateElem(SqList L,ElemType e){
//在顺序表L中查找第一个元素值等于e的元素,并返回其位序 
	int i;
	for(i=0;i<L.length;i++)
		if(L.data[i]==e)
			return i+1;//下标为i的元素值等于e,返回其位序i+1
	return 0;//退出循环,说明查找失败 
}//平均时间复杂度O(n)

链式存储

单链表中结点类型描述

 typedef struct LNode{//定义单链表结点类型
 	ElemType data;//数据域
	 struct LNode *next;//指针域 
 }LNode,*LinkList; 

头插法建立单链表

 

LinkList List_HeadInsert(LinkList &L){//逆向建立单链表
	LNode *s;
	int x;
	L=(LinkList)malloc(sizeof(LNode));//创建头结点
	L->next=NULL;//初始为空链表
	scanf("%d",&x);//输入结点的值
	while(x!=9999){//输入9999表示结束
		s=(LNode*)malloc(sizeof(LNode));//创建新结点
		s->data=x;
		s->next=L->next;
		L->next=s;//将新结点插入表中,L为头指针
		scanf("%d",&x); 
	} 
	return L;
} //单链表长为n,总时间复杂度为O(n) 

尾插法建立单链表

 

LinkList List_TailInsert(LinkList &L){//正向建立单链表 
	int x;//设元素类型为整型 
	L=(LinkList)malloc(sizeof(LNode));
	LNode *s,*r=L;//r为表尾指针
	scanf("%d",&x);//输入结点的值
	while(x!=9999){//输入9999表示结束
	s=(LNode *)malloc(sizeof(LNode));
	s->data=x;
	r->next=s;
	r=s;//r指向新的表尾结点
	scanf("%d",&x); 
	}
	r->next=NULL;//尾结点指针置空
	return L; 
} 

按序号查找结点值

LNode *GetElem(LinkList L,int i){//查找操作时间复杂度O(n) 
	int j=1;//计数,初始为1
	LNode *p=L->next;//第1个结点指针赋给p
	if(i==0)
	return L;//返回头结点
	if(i<1)
	return NULL;//若i无效,则返回NULL 
	while(p&&j<i){//从第1个结点开始找,查找第i个结点
		p=p->next;
		j++; 
	}
	return p;//返回第i个结点的指针,若i大于表长,则返回NULL 
}

按值查找表结点

LNode *LocateElem(LinkList L,ElemType e){O(n) 
	LNode *p=L->next;
	while(p!=NULL&&p->data!=e)//从第1个结点开始查找data域为e的结点
		p=p->next;
	return p;//找到后返回该结点指针,否则返回NULL 
}

插入结点操作

 

1->后插(查找为O(n),插入为O(1))

p=GetElem(L,i-1);//查找插入位置的前驱结点
s->next=p->next;
p-next=s; 

2->前插(转化为后插)

交换*s与*p,既满足逻辑关系,又使时间复杂度为O(1)

p=GetElem(L,i-1);//查找插入位置的前驱结点
s->next=p->next;
p-next=s; 
temp=p->data;//交换 
p->data=s->data;
s->data=temp; 

删除结点操作

 

p=GetElem(L,i-1);//查找删除位置的前驱结点   O(n)
q=p->next;//令q指向被删除结点
p->next=q->next;//将*q结点从链中“断开”
free(q);//释放结点的存储空间 

双链表

typedef struct DNode{//定义双链表结点类型
	ElemType data;//数据域
	struct DNode *prior,*next;//前驱和后继指针 
}DNode,*DLinkList; 

插入操作

 

s->next=p->next;//将结点*s插入到结点*p之后
p->next->prior=s;
s->prior=p;
p->next=s; 

删除操作

 

p->next=q->next;
q->next->prior=p;
free(q);

循环链表

 

在循环双链表L中,某结点*p为尾结点时,p->next==L;当循环双链表为空表时,其头结点的prior域和next域都等于L。
​​​​​​​ 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵩韵儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值