线性表的认识和操作

线性表包括

顺序表、单链表、双向链表、循环链表

1. 线性表相关概念
线性表(Linear List)

是由n(n≥0)个具有相同特性(数据类型)的数据元素结点)a1,a2,...,ai-1,ai,ai+1,...,an组成的有限序列。

L= (A1, A2, ... , Ai, Ai+1.…. , An)i           (1≤i≤n)

a1为线性起点(起始结点),an为线性终点(终端结点)。对于每一个数据元素ai,ai-1为它的直接前驱,ai+1为它的直接后继。n为数据元素总个数,即表长。当n=0时,线性表为空表。

Ai 是线性表中的 “ 第 i 个” 元素线性表中的位序( 位序从1开始,数组下标从0开始 )


线性表按存储分类

不破坏数据的前后次序,将它们连续存储在内存空间中,按这样的存储方案称为顺序存储结构(简称顺序表)。

 将所有数据分散存储在内存中,按这样的存储方案称为链式存储结构(简称链表)。


1.顺序表的操作见

https://blog.csdn.net/2301_80433738/article/details/139016821?spm=1001.2014.3001.5502


2.线性链表的一些认识和操作

关于线性链表的知识:结点(节点),头结点、头指针和首元结点

结点(Node):

链表中,每个数据元素都配有一个指针,结点由数据域和指针域构成。

typedef struct node {
	int d; //数据域
	struct node* next; //指针域
};

对数据域的定义;数据域是描述字段技术属性的集合,包括数据类型、长度、精度等 

对指针域也类似;

数据域用来存储元素的值,指针域用来存放指针。数据结构中,通常将上图这样的整体称为结点。


头指针:始终指向链表中第一个结点的指针,通常用其来标识一个链表。头结点是链表中的首元结点之前,头指针之后的一个结点。是一个链表中的第一个结点,其数据域内用于存放空表标志和表长信息等。

头结点:某些场景中,为了方便解决问题,会故意在链表的开头放置一个空结点,这样的结点就称为头结点。也就是说,头结点是位于链表开头、数据域为空(不利用)的结点。

🥝注意(链表中头节点不一定有,而链表一定有头指针)

首元结点:指的是链表开头第一个存有数据的结点。


操作 

定义节点数据结构

typedef struct node {
	int d;
	struct node* next;
};

 

输出显示线性链表 

void prtList(node* head) //负责输出显示线性链表
{
	cout << "当前链表的内容为:";
	while (head != NULL) {
		cout << head->d << ' ';
		head = head->next;
	}
	cout << endl;
}

 

头插法创建并初始化一个长度为K的链表,(链表内容是自然数 )

void CreateListHead(node *head,int K)
{
	//head为传入的头指针
	//K为表长
	head = NULL;
	node* p;
	for (int i = 1; i < K; i++) {
		p = new node;
		p->d = i;

		p->next = head;

		head = p;//head指向p结点 为下一个p(i+1)指向p做准备

	}


 

 逆转单链表(不带头节点)

例举 递归法和🚩头插法

头插法比较容易理解

node* invertList(node* head) //负责逆转链表的函数
{
	if ( head==NULL||head->next ==NULL) {
		return head;
	}
	node* n_head = invertList(head->next);
	head->next->next = head;
	head->next = NULL;
	return n_head;

}

 


node* invertList(node* head) {
	node* p = NULL, * nhead = NULL;
	while (head != NULL) {
		p = head;	//指向 NULL 的指针变量 p 重新指向另一个 node结构类型的指针 head
		head = head->next;
		p->next = nhead;
		nhead = p;
	}
	return nhead;
}

 分析头插法: 先定义两个node*类型的指针 p 和 nhead(new_head) 

                      令p重新指向head  p现在代表head(旧); 然后head指向head->next代表的结点

                        获得新的head(新) 为下一次循环做准备;

                        p->next指向待传出的反转链表头指针( 此时p->next代表的是最开始head(旧)的head->next 由于头插法创建的单链表head->next指向的是最后一个结点;

                        到循环的最后一步前 nhead的第一个首元结点即为原列表的最后一个结点;

                        然后nhead指向p(可由图 此时p指向i+1即首元结点);

                        继续循环完成至head==NULL;

        1,3行可观察到p始终指向最新的一个结点的前一个结点获取next为nhead链接做准备;

        2,4行为下次循环做准备

 

         熟悉这四行主要代码后多练习030;


          合并两个单链表(不含头结点)
node* combineList(node* AH, node* BH) //负责合并链表
{
	node* ch;//新链表(最终为合并的链表
	node* r;
	node* p = AH;
	node* q = BH->next;

	ch = BH, ch->next = NULL,r=ch;
	//r代表ch开始为ch构建新链表
	//ch->next=NULL 由于为头插法创建的BH BH的next指向最后一个结点
	while (p != NULL && q != NULL) {
		if (p->d > q->d) {
			r->next = p; p = p->next;//p->d大于q->d则r接p p往下一个走 r往下一个NULL结点走;
			r = r->next;
		}
		else {
			r->next = q; q = q->next;//同上
			r = r->next;
		}
	}
	if (p != NULL)r->next = p;
	if (q != NULL)r->next = q;
	return ch;
}

未完

 

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值