考研数据结构之线性表(2)

了解完线性表的基础概念后,接下类来就看看考研中线性表如何去考。
线性表考点分了以下几类:

  • 特性对比
  • 移动次数计算和静态链表
  • 插入和删除
  • 建表
  • 逆置
  • 取最值
  • 归并

本篇文章讲解前四个考点
剩下四个请看下篇文章

特性对比问题

主要对比操作和存储特性方面
1.插入删除问题
顺序表插入:(最右边的开始移动)
在这里插入图片描述
在这里插入图片描述
顺序表删除:
从前往后移动元素,只需要把要删除的元素覆盖掉就好了

单链表的插入:
在这里插入图片描述
在这里插入图片描述
单链表的删除操作:
上面的倒过来就是
对比
在顺序表中插入和删除元素可能会导致移动大量元素的连带操作(插入或删除发生在表尾位置例外),而链表不会

2.元素的定位问题
顺序表只要知道某个元素的下标就可以定位到这个元素,对于链表需要指针一个个走一遍
对比
1.在单链表中找到任意一个结点的位置不像顺序表那么简单,因为顺序表支持随机存取(任意存取),而单链表不支持;

2.为了尽可能弥补上一条中单链表的不足,开发了双链表,循环链表存储结构,这些结构可以子啊仅知道链表中任一结点地址的情况下推知其余所有的节点的地址,但仍然不支持随机存取。

3.有时候还会给链表定义一个额外的指针,最常见的是表尾指针,它指向表中最后一个结点。可以借助它来提高某些常用操作的执行效率

3.存储空间相关问题

线性表采用顺序存储结构,必须占用一片连续的存储单元,而采用链式存储结构则不是这样;
对比
从表的整体来看,一般顺序表的存储空间利用率低于链表;而从单个存储单元来看,顺序表的存储空间利用率要高于链表

元素移动次数计算和静态链问题

一.元素移动次数计算
移动次数计算只会发生在顺序表中,主要有两种题目类型
1.在某个位置插入元素会导致多少个元素的移动
在i位置之前插入元素,需要移动n-i个元素
2.在每一个位置上插入一个元素所导致的平均移动次数
在这里插入图片描述
删除元素和插入类似

在这里插入图片描述
静态链表
说一下什么是静态什么是动态,其实就是指存储空间静态分配就是指一次分配(顺序表),而动态分配是多次分配
静态链表结点类型的定义

 typedef struct
 {
 	int data;
 	int next;//下标
 }SLNode;

下图是一个线性表,里面有一些元素,上面就是我们构造的结点结构体类型,现在我们要把这个线性表存在一个静态链表中
在这里插入图片描述
首先应该为静态链表分配存储空间,既然是一次分配,那么就可以用一个数组来搞定
下面定义了 一个SLNode类型的数组,长度为maxSize,就是一下分配了maxsize个静态链表的结点空间

SLNode SLink[maxSize];

在考研中常常是给你一个建好的静态链表然后对存储空间的细节进行考察

细节如下
反应的是一个数组,有两行分别是index,也就是数组的下标,另一行就是数据了,只是我们存的数据有两个分量所以长得有点象三行,next存的是指针,但这个指针不是严格意义上的指针型变量,他存的是指向下一节点的地址,但这个地址也不是严格意义上的地址,它是指数组的下标,是不是很像链表
在这里插入图片描述
下面是一些基本操作
定义一个静态链表的指针,并让他指向结点A(对比一般链表)

 int p =Ad0;    //定义一个指针
 SLink[p].data;//取p指针指向的结点值,类比p->data
 SLink[p].next;//取p后继节点指针,类比p->next;

插入元素的操作
//在p后插入结点q:

SLink[q].next=SLink[p].next;
SLink[p].next=q;

插入和删除操作

链表的插入和删除操作

1.单链表的插入
在这里插入图片描述1.单链表的删除
在这里插入图片描述
3.插入特殊情况
含有头节点的单链表无特殊情况(因无论那个位置都可以看作在后面插入)
不含的如果在第一个元素之前插入就会不一样
在这里插入图片描述
在这里插入图片描述
给链表设置头结点,可以使得在第一个数据结点之前插入一个新节点和删除第一个数据节点的操作同表中部结点的这些操作统一起来,方便写代码

带有头结点的链表,其头指针不随操作而改变,可以减少错误

4.双链表的插入
在这里插入图片描述

5.双链表的删除
在这里插入图片描述
顺序表的插入和删除操作
插入注意事项
在这里插入图片描述

//创建一个表
int sqList[maxSize]={1,2,3,...,n}
int length=n

int insertElem(int sqlList[],int &length,int p,int e)
{
	if(p<0||p>length||length==maxSize)
	return 0;
	for(int i=length-1;i>=p;--1)
	sqList[i+1]=sqList[i];
	sqList[p]=e;
	++length;
	return 1;
}

删除注意事项
在这里插入图片描述

int deleteElem(int sqList[],int &length,int p, int &e)
{
	if(p<0||p>length-1)
	return 0;
	e=sqList[p];
	for(int i=p;i<length-1;++i)
	sqList[i]=sqList[i+1]
	--length;
	return 1;
}

建表

1.顺序表建表
在这里插入图片描述
链表建表

尾插法
在这里插入图片描述
一个例子
要求实现两个函数,输入n个数据,采用尾插法创建单链表并打印。例如:如果输入4 ,再输入3 7 9 5,则应打印输出3 7 9 5。
链表结点结构定义:

struct Node {    //链表结点
    int data;    //数据
    struct Node* link;    //指向下一个结点的指针
};

函数接口定义:

/* 尾插法建立单链表:返回单链表的头指针 */
struct Node* buildLinkedList(int* arr, int n); /* 尾插法建立单链表 */
void printLinkedList(struct Node* head);       /* 打印链表 */

其中arr和n是用户传入的参数,n的值不超过100000。head为单链表的头指针。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>//malloc函数
 
struct Node {    //链表结点
    int data;    //数据
    struct Node* link;    //指向下一个结点的指针
};
 
/* 尾插法建立单链表:返回单链表的头指针 */
struct Node* buildLinkedList(int* arr, int n); /* 尾插法建立单链表 */
void printLinkedList(struct Node* head);       /* 打印链表 */
 
int main(int argc, char const *argv[]) {
    int n, i;
    int* a;
    scanf("%d", &n);
    a = (int*)malloc(n * sizeof(int));	//动态内存分配申请数组空间
    for (i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
 
    struct Node* head = NULL;	//声明一个指针变量head
 
    //创建链表,把返回的头指针赋值给head指针变量
    head = buildLinkedList(a, n);
 
    //打印链表:整个链表用head来代表。
    printLinkedList(head);
 
    free(a);	//释放存储空间
 
    return 0;
}
 
/* 请在这里填写答案 */
struct Node* buildLinkedList(int* arr, int n){
	struct Node*p,*pre,*head;
	head=(struct Node*)malloc(sizeof(struct Node));
	head->link=NULL;
	pre=head;
	for(int i=0;i<n;i++){
		p=(struct Node*)malloc(sizeof(struct Node));
		p->data=arr[i];
		p->link=NULL;
		pre->link=p;
		pre=p;
	}
	return head;
}
void printLinkedList(struct Node* head){            
	head=head->link;
	printf("%d",head->data);
	head=head->link;
	while(head!=NULL){
		printf(" %d",head->data);
		head=head->link;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值