线性表简述,例题

基本概念
        线性表是具有相同数据类型的n个数据元素的有限序列。线性表中的相邻元素存在顺序关  系,ai-1称为ai的之间前驱,ai+1称为直接后继。


        二元组表示:D={ai | 1<= i <= n, n >=0}     R={<ai-1,ai> | ai-1, ai E D, 1<=i<=n} 是一个序偶 集合。


特点:
        ①有且仅有一个开始结点(a1),它没有直接前驱。
        ②有且仅有一个终端结点(an),它没有直接后继。
        ③除了开始结点和终端结点,其余结点都是有且仅有一个直接前驱和直接后继。



顺序存储
      用一组地址连续的存储单元一次存储线性表的数据元素,顺序表的逻辑顺序和物  理顺序是一致的。
  存储特点:
        ①顺序表的逻辑顺序和物理顺序是一致的
        ②其中任一数据元素都可以随机存取
  基本运算实现:
        (1)类型定义:DataType data[MAX];  int Length;
        (2)初始化:L->Length=0;
        (3)建立:for(i=0;i<n;i++)   scanf(“%d”,&L->data[i]);  L->Length=i;
        (4)查找:
                ①按位置查找:if( i<1 || i>Length )return 0;   else{ *x = L->data[i]; return 1;}
                ②按值查找:while(i<Length && L>data[i] != x)i++;  if(i>=L>Length)return 0; else return i+1;
        (5)插入操作:
                ①判满:if(L->Length >= MAX){return -1;}
                ②检查位置正确:if( i<1 || i > L->Length+1 ){return 0;}
                ③若在表尾插入:if(i == L->Length+1){L->data[i-1] = x; L->Length++; return 1;}
                ④若插入在表中:for( j = L->Length-1; j >= i-1; j--)  L->data[j+1] = L->data[j];  L->data[i-1] = x;L->Length++; return 1;


4.顺序插入算法的时间性能:长度为n的线性表插入一次平均移动元素次数n/2,其时间复杂度为O(n)。
5.顺序删除算法的时间性能:长度为n的线性表中删除一个元素所需的平均移动次数n-1/2,时间复杂度为O(n)。
6.长度为n的顺序表中,删除第i个元素,需向前移动n-i个元素;在第i个元素前插入元素需向后移动n-i+1个元素。



链式存储
单链表
(1)定义:线性表的链式存储结构是用一组任意的存储单元存储线性表的数据元素,为了反映数据原始直接的逻辑关系,每个数据元素不仅要表示它的具体内容(数据域),还要附加一个表示它直接后继元素存储位置的信息(指针域),这样构成的链表叫单链表。
(2)头结点:单链表分为带头结点和不带头结点,头结点数据域可以不存储信息,其指针域存储链表第一个结点的地址,当指针域为空时,表示此表为空。
(3)操作实现
①申请空间结点:
②插入结点(p后插s):s->next=p->next   p->next=s;
③删除结点:if(p->next != NULL && j==i-1) s=p->next  x=s->data  p->next=s->next  free(s)  
(4)链表插入算法的时间复杂度为O(n),删除也是O(n)两者都耗费在查找上。


循环链表
(1)定义:对于单链表,最后一个结点指针域为空,如果将改链表中最后一个结点指针域指向头结点,整个链表形成了环,构成了循环单链表。
(2)操作:用尾指针rear指向链表最后一个结点,查找终端结点就是rear,首结点是rear->next->next。


双向链表
(1)定义:在单链表的基础上加一个指向其直接前驱的指针域prior。
(2)操作:
①插入结点:s->prior=p->prior;  p->prior->next=s;  s->next=p;  p->prior=s;
②删除结点:p->prior->next=p->next;  p->next-prior=p->prior;  free(p);



顺序表和链表的比较
1.顺序表
(1)优点:
①具有按元素序号随机访问,存取的特点
②节省存储,无须为表示线性表中元素的逻辑关系额外增加存储开销
③方法简单容易实现
(2)缺点
①进行插入和删除时,平均移动次数是线性表长度的一半,因此对长度较大的线性表操作效率低
②预先分配存储空间,若过大会浪费,过小又会造成操作失败
2.链表
(1)优点:
①不用预先分配存储空间。
②插入和删除只需修改指针域,不需移动元素。
(2)缺点:
①每个结点需要额外占用存储空间,存储密度小。
②存储结构是非随机存储结构,查找元素需从头开始。
3.运用时应采用什么结构?
(1)空间考虑
①线性表长度变化大的时,难以确定大小时,应采用链式。
②长度变化不大的时候,为了节约存储空间,宜采用顺序表。
(2)时间考虑
①当线性表主要是查找时,应采用顺序表存储结构。
②当线性表主要是插入和删除,应用链式存储结构。
(3)语言考虑
①链表基于指针的,其使用受高级语言的限制。


例题

洛谷P1996 约瑟夫问题

#include<bits/stdc++.h>
using namespace std;
int net[1000005];

int main(){
    int n,m;
    cin>>n>>m;//输入n、m
    for(int i=0;i<n;i++)//初始化
    	net[i]=i+1;
	net[n]=1;
	int p=0;//p相当于一个指针,指向出圈数的前一位
    
	for(int i=1;i<=n;i++){//开始模拟出圈过程
		for(int j=1;j<m;j++)
			p=net[p];//p位置右移
		cout<<net[p]<<" ";//右移2次之后,输出出圈人的位置
		net[p]=net[net[p]];//删掉出圈人(本点直接指向下下点)
	}
	return 0;
}
/*
用循环链表来写比较清晰,先建立一个可以指向下一个数字的数组:
net[1]指向数字2,net[2]指向数字3...

net	    1	2	3	4	5	6	7	8	9	10
数字    2	3	4	5	6	7	8	9	10	1

*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值