【数据结构C++】02-1线性结构-线性表

02线性结构

2.1线性表

例2.1:多项式的表示

①a[i]数组:项 xi 的系数 ai
相加过程:对应项直接相加。
优缺点:表示方便,但是在表示 x+x^2000 ^时存在空间浪费。

②(ai,i)结构数组(仅表示非零项):数组分量由系数ai、指数i组成的结构,对应一个非零项
相加过程:先比较指数大小,大的直接取出再比较下一项,相等则系数相加。
优缺点:节省空间,操作效率也不低。

③链表:每个节点储存多项式中的一个非零项,包括系数、指数两个数据域以及一个指针域

2.1.1线性表定义

由同类型数据元素构成有序序列的线性结构。(长度、空表、表头、表尾)

线性表的抽象数据类型描述
在这里插入图片描述

2.1.2顺序存储

(动态数组):

头文件
#pragma once

class myList {
public:

	myList();						//默认构造
	myList(int n);					//有参构造
	myList(const myList& other);	//拷贝构造
	void printList();				//打印输出
	int Find(int x);				//查找,返回X在表中第一次出现的位置
	int findKth(int k);				//返回第k个元素
	void push_back(int x);			//尾插
	void Insert(int i, int x);		//指定位置i插入
	void Delete(int i);				//删除
	void clear();					//清空
	int getLength();				//返回长度

private:
	int List_length;			//线性表长度
	int List_capacity;			//线性表容量
	int* List_data;				//数据数组
};
----------------------------------------------------------------------
源文件
#include "myList.h"
#include<iostream>
using namespace std;

//默认构造
myList::myList()
{
	this->List_data = nullptr;
	this->List_capacity = 0;
	this->List_length = 0;
}

//有参构造,参数n为线性表容量大小
myList::myList(int n)
{
	if (n <= 0) {
		cout << "输入不合法,初始化失败,请检查" << endl;
		myList();
		return;
	}
	this->List_length = 0;
	this->List_capacity = n;
	this->List_data = (int*)malloc(List_capacity*sizeof(int));
}

//拷贝构造
myList::myList(const myList& other)
{
	this->List_capacity = other.List_capacity;
	this->List_length = other.List_length;
	this->List_data = new int[this->List_capacity];
	for (int i = 0; i < this->List_length; i++) {
		this->List_data[i] = other.List_data[i];		//警告:	C6386	写入到“this->List_data”时缓冲区溢出: 可写大小为“List_capacity * 4”个字节,但可能写入了“8”个字节。
	}
}

//打印输出
void myList::printList()
{
	for (int i = 0; i < this->List_length; i++) {
		cout << this->List_data[i] << endl;
	}
}

//查找,返回X在表中第一次出现的位置
int myList::Find(int x)
{
	int i = 0;
	while (i < this->List_length && this->List_data[i] != x)
		i++;
	if (i >= this->List_length) return -1;
	else return i;
}

//返回第k个元素
int myList::findKth(int k)
{
	if (k < 0 || k >= this->List_length) {
		cout << "超出索引范围的k,请检查" << endl;
		return -1;
	}
	else return this->List_data[k];
}

//尾插
void myList::push_back(int x)
{
	if (this->List_length == this->List_capacity) {
		cout << "表满,无法插入" << endl;
		return;
	}
	this->List_data[this->List_length] = x;
	this->List_length++;
}

//指定位置i插入
void myList::Insert(int i, int x)
{
	if (this->List_length == this->List_capacity) {
		cout << "表满,无法插入" << endl;
		return;
	}
	if (i < 0 || i > this->List_length) {
		cout << "插入位置超出长度范围" << endl;
		return;
	}
	for (int j = this->List_length; j > i; j--) {
		this->List_data[j] = this->List_data[j - 1];
	}
	List_data[i] = x;
	List_length++;
	return;
}

//删除
void myList::Delete(int i)
{
	if (i < 0 || i > this->List_length-1) {
		cout << "位置超出范围,请检查" << endl;
		return;
	}
	for (int j = i; j < this->List_length - 1; j++) {
		this->List_data[j] = this->List_data[j + 1];
	}
	this->List_length--;
	return;
}

//清空
void myList::clear()
{
	List_length = 0;
	List_data = nullptr;
	free(List_data);
}

//返回长度
int myList::getLength()
{
	return this->List_length;
}
2.1.3链式存储

(链表):

头文件
#pragma once

class listNode {
public:
	listNode* Pre;
	listNode* Next;
	int var;
};

链表类头文件:
#pragma once
#include "listNode.h"

class myList {
public:
	myList();						//默认构造
	myList(const myList& other);	//拷贝构造
	void printList();				//打印输出
	listNode* Find(int x);				//查找,返回X在表中第一次出现的位置
	listNode* findKth(int k);				//返回第k个元素
	void push_back(int x);			//尾插
	void Insert(int i, int x);		//指定位置i插入
	void Delete(int i);				//删除
	int getLength();				//返回长度
	~myList();						//析构函数

private:
	listNode* List_head;		//表头
	listNode* List_tail;		//表尾
	int List_length;			//表长
};
-------------------------------------------------------------------
源文件:
#include<iostream>
#include "myList.h"
using namespace std;

//默认构造
myList::myList()
{
	List_head = new listNode();
	List_tail = new listNode();
	List_head->Pre = nullptr;
	List_head->Next = List_tail;
	List_tail->Pre = List_head;
	List_tail->Next = nullptr;
	List_length = 0;
}

//拷贝构造
myList::myList(const myList& other)
{
	List_head = new listNode();
	List_head->Pre = nullptr;
	List_tail = new listNode();
	List_head->Next = List_tail;
	List_tail->Pre = List_head;
	List_length = 0;
	listNode* temp = other.List_head;
	while (temp->Next != other.List_tail) {
		temp = temp->Next;
		List_tail->var = temp->var;
		listNode* newNode = new listNode();
		newNode->Pre = List_tail;
		List_tail->Next = newNode;
		List_tail = newNode;
		List_length++;
	}
}

//打印输出
void myList::printList()
{
	if (List_length == 0) {
		cout << "链表为空" << endl;
		return;
	}
	listNode* temp = List_head->Next;
	while (temp != List_tail) {
		cout << temp->var << endl;
		temp = temp->Next;
	}
}

//查找,返回X在表中第一次出现的位置
listNode* myList::Find(int x)
{
	listNode* temp = new listNode();
	temp = List_head->Next;
	while (temp != List_tail && temp->var != x) {
		temp = temp->Next;
	}
	if (temp != List_tail) return temp;
	else return NULL;
}

//返回第k个节点
listNode* myList::findKth(int k)
{
	listNode* temp = new listNode();
	temp = List_head->Next;
	int i = 1;
	while (temp != List_tail && i < k) {
		temp = temp->Next;
		i++;
	}
	if (i == k) return temp;
	else return NULL;
}

//尾插
void myList::push_back(int x)
{
	listNode* newNode = new listNode();
	newNode->Next = nullptr;
	newNode->Pre = List_tail;
	List_tail->Next = newNode;
	List_tail->var = x;
	List_tail = newNode;
	List_length++; 
}

//指定位置i插入
void myList::Insert(int i, int x)
{
	listNode* s = new listNode();
	listNode* p = new listNode();
	p = findKth(i-1);
	if (p == NULL) {
		cout << "输入参数i非法" << endl;
	}
	else {
		s->var = x;
		s->Next = p->Next;
		s->Pre = findKth(i)->Pre;
		p->Next = s;
		findKth(i)->Pre = s;
		List_length++;
	}
}

//删除节点
void myList::Delete(int i)
{
	listNode* p = new listNode();
	listNode* s = new listNode();
	p = findKth(i-1);
	s = findKth(i);
	if (p == NULL) {
		cout << "输入参数i非法" << endl;
	}
	else {
		p->Next = findKth(i + 1);
		findKth(i+1)->Pre = p;
		delete s;
		List_length--;
	}
}

//返回长度
int myList::getLength()
{
	//return List_length;
	listNode* temp = new listNode();
	temp = List_head->Next;
	int l = 0;
	while (temp != List_tail) {
		temp = temp->Next;
		l++;
	}
	return l;
}

//析构函数
myList::~myList()
{
}
2.1.4 广义表

用于表示二元多项式
在这里插入图片描述

​ 广义表是*线性表的推广,线性表中n个元素都是基本的单元素,广义表中这些元素不仅可以是单元素也可以是另一个广义表*。

在这里插入图片描述

通过tag标志域来识别后面是广义表还是单元素。

2.1.5 多重链表

多重链表中节点的指针域有多个,但有多个指针域的不一定是多重链表,如双向链表,多重链表可以用来表示树、图等复杂数据结构。

十字链表:
在这里插入图片描述
注:图片均源自于中国大学MOOC浙大《数据结构》课程
https://www.icourse163.org/course/ZJU-93001?tid=1465570445

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

摘提子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值