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