1. 概念
2. 线性表的特点
3. 线性表的顺序存储
(ps:存储密度:指一个结点中数据元素所占的存储单元数和整个结点所占的存储单元之比,顺序表的存储密度为1,链式存储密度小于1)
5. 线性表的链式存储
#include
#include
#include
using namespace std;
struct Info {
int number;
string name;
};
struct Node {
Info data;
struct Node *next;
Node(Info info):data(info), next(NULL){}
};
class LinkList{
public:
//构造函数
LinkList();
//析构函数
~LinkList();
//在头部插入
void InsertHead(Info data);
//在尾部插入
void InsertTail(Info data);
//插入
void Insert(Info data, int pos);
//删除
void Remove(Info data);
//查找
int Find(Info data);
//倒序
void Reverse();
//链表长度
int Length();
//打印
void Print();
private:
Node *head;
int length;
};
(2)linkList.cpp
#include"linklist.h"
using namespace std;
LinkList::LinkList() {
head = NULL;
length = 0;
}
LinkList::~LinkList() {
Node *temp;
for (int i = 0; i < length; i++) {
temp = head;
head = head->next;
delete temp;
}
}
void LinkList::InsertHead(Info data) {
Insert(data, 0);
}
void LinkList::InsertTail(Info data) {
Insert(data, length);
}
void LinkList::Insert(Info data, int pos) {
if (pos < 0) {
cout << "Pos must greater than 0." << endl;
return;
}
Node *node = new Node(data);
Node *temp = head;
if (pos == 0) {
node->next = temp;
head = node;
length++;
return;
}
if (pos == length) {
while (temp->next) {
temp = temp->next;
}
temp->next = node;
length++;
return;
}
int index = 1;
while (temp != NULL && index < pos) {
temp = temp->next;
index++;
}
if (temp == NULL) {
cout << "Insert failed." << endl;
return;
}
node->next = temp->next;
temp->next = node;
length++;
}
void LinkList::Remove(Info data) {
int pos = Find(data);
if (pos == -1) {
cout << "No such data." << endl;
return;
}
if (pos == 0) {
Node *p = head;
head = head->next;
length--;
delete p;
return;
}
int index = 1;
Node *temp = head;
while (index < pos) {
temp = temp->next;
index++;
}
Node *p = temp->next;
temp->next = temp->next->next;
delete p;
length--;
}
int LinkList::Find(Info data) {
int index = 0;
Node *temp = head;
while (temp != NULL) {
if ((temp->data.name == data.name) && (temp->data.number == data.number)) {
return index;
}
temp = temp->next;
index++;
}
return -1;
}
void LinkList::Reverse() {
if (head == NULL) return;
Node *curNode = head;
Node *nextNode = curNode->next;
Node *temp;
while (nextNode != NULL) {
temp = nextNode->next;
nextNode->next = curNode;
curNode = nextNode;
nextNode = temp;
}
head->next = NULL;
head = curNode;
}
int LinkList::Length() {
return length;
}
void LinkList::Print() {
if (head == NULL) {
cout << "Empty list." << endl;
return;
}
Node *temp = head;
while (temp != NULL) {
cout << temp->data.number << "," << temp->data.name << endl;
temp = temp->next;
}
}
(3)main.cpp
#include"linklist.h"
using namespace std;
int main() {
LinkList head;
Info info0, info1, info2, info3;
info0.number = 000; info0.name = "aaa";
info1.number = 001; info1.name = "bbb";
info2.number = 002; info2.name = "ccc";
info3.number = 003; info3.name = "ddd";
//InsertHead(), Insert(), Print()
head.InsertHead(info0);
head.InsertTail(info1);
head.InsertTail(info3);
head.Insert(info2, 2);
cout << "Insert info0 to info3." << endl;
head.Print();
cout << endl << endl;
//Reverse()
head.Reverse();
cout << "Reverse List." << endl;
head.Print();
cout << endl << endl;
//Find(), Remove, Print()
head.Remove(info0);
head.Remove(info2);
cout << "Remove info0, info2." << endl;
head.Print();
cout << endl << endl;
//Length
int len = head.Length();
cout << "Length is " << len << "." << endl;
system("pause");
return 0;
}
#include
#include
#include
using namespace std;
class doubleLinkList {
public:
struct Node {
int data;
struct Node *next;
struct Node *pre;
Node(int data):data(data), next(NULL), pre(NULL){}
};
doubleLinkList();
~doubleLinkList();
void InsertHead(int data);
void InsertTail(int data);
void Insert(int data, int pos);
void Remove(int data);
int Find(int data);
void Reverse();
void Print();
int Length();
private:
Node *head;
int length;
};
(2)doubleLinkList.cpp
#include "doubleLinkList.h"
using namespace std;
doubleLinkList::doubleLinkList() {
head = NULL;
//head->next = head->pre = NULL;
length = 0;
}
doubleLinkList::~doubleLinkList() {
Node *temp;
for (int i = 0; i < length; i++) {
temp = head;
head = head->next;
delete temp;
}
}
void doubleLinkList::InsertHead(int data) {
Insert(data, 0);
}
void doubleLinkList::InsertTail(int data) {
Insert(data, length);
}
void doubleLinkList::Insert(int data, int pos) {
if (pos < 0) {
cout << "Pos Must Greater Than 0." << endl;
return;
}
Node *node = new Node(data);
Node *temp = head;
if (pos == 0) {
node->next = temp;
if(temp != NULL)
temp->pre = node;
head = node;
length++;
return;
}
if (pos == length) {
while (temp->next) {
temp = temp->next;
}
temp->next = node;
node->pre = temp;
node->next = NULL;
length++;
return;
}
int index = 1;
while (index < pos) {
temp = temp->next;
index++;
}
if (temp == NULL) {
cout << "Insert Failed." << endl;
return;
}
node->next = temp->next;
if (temp->next != NULL)
temp->next->pre = node;
temp->next = node;
node->pre = temp;
length++;
}
int doubleLinkList::Find(int data) {
int pos = 0;
Node *temp = head;
for (int i = 0; i < length; i++) {
if (temp->data == data) {
return pos;
}
temp = temp->next;
pos++;
}
return -1;
}
void doubleLinkList::Remove(int data) {
int pos = Find(data);
if (pos == -1) {
cout << "No such data." << endl;
}
if (pos == 0) {
Node *temp = head;
head = head->next;
delete temp;
length--;
return;
}
int index = 1;
Node *temp = head;
while (index < pos) {
temp = temp->next;
index++;
}
Node *p = temp->next;
temp->next = temp->next->next;
if (temp->next != NULL) {
temp->next->pre = temp;
}
delete p;
length--;
}
void doubleLinkList::Reverse() {
if (head == NULL) return;
Node *curNode = head;
Node *nextNode = curNode->next;
Node *temp;
while (nextNode != NULL) {
temp = nextNode->next;
nextNode->next = curNode;
curNode->pre = nextNode;
if(temp != NULL)
temp->pre = curNode;
curNode = nextNode;
nextNode = temp;
}
head->next = NULL;
head = curNode;
}
void doubleLinkList::Print() {
if (head == NULL) {
cout << "Empty list." << endl;
return;
}
Node *temp = head;
while (temp != NULL) {
cout << temp->data << endl;
temp = temp->next;
}
}
int doubleLinkList::Length() {
return length;
}
(3)main.cpp
#include"doubleLinkList.h"
using namespace std;
int main() {
int data[5] = { 0, 1, 2, 3, 4 };
doubleLinkList head;
//InsertHead(), InsertTail(), Insert(), Print()
head.InsertHead(data[0]);
head.InsertTail(data[1]);
head.InsertTail(data[2]);
head.Insert(data[3], 3);
cout << "Insert data[0] to data[3]." << endl;
head.Print();
cout << endl << endl;
//Reverse()
head.Reverse();
cout << "Reverse List." << endl;
head.Print();
cout << endl << endl;
//Find(), Remove, Print()
head.Remove(data[0]);
head.Remove(data[2]);
cout << "Remove data[0], data[2]." << endl;
head.Print();
cout << endl << endl;
//Insert(),Print()
head.InsertHead(data[0]);
head.Insert(data[4], 3);
cout << "Insert data[0], data[4]." << endl;
head.Print();
cout << endl << endl;
//Length
int len = head.Length();
cout << "Length is " << len << "." << endl;
system("pause");
return 0;
}
1. 概念
队列(Queue)是只允许在一端进行插入操作,另一端进行删除操作的线性表。允许插入的端是队尾,允许删除的端是队头。
2. 顺序队列
#include
using namespace std;
template <class T>
class LinerQueue {
public:
LinerQueue(int len);
~LinerQueue();
bool isEmpty();
int Length();
void Rear();
void Front();
void Push(T item);
void Pop();
private:
T *queue;
int front;
int rear;
int length;
};
(2)linerQueue.cpp
#include"linerQueue.h"
using namespace std;
template <class T>
LinerQueue<T>::LinerQueue(int len) {
if (len < 1) {
cout << "Lenfth must > 0." << endl;
return;
}
queue = new T[len];
length = len;
front = rear = 0;
}
template <class T>
LinerQueue<T>::~LinerQueue() {}
template <class T>
bool LinerQueue<T>::isEmpty() {
return rear == front;
}
template <class T>
int LinerQueue<T>::Length() {
return length;
}
template <class T>
void LinerQueue<T>::Front() {
if (isEmpty()) {
cout << "Queue is empty." << endl;
return;
}
cout << "Front element is : " << queue[(front + 1) % length] << endl;
}
template <class T>
void LinerQueue<T>::Rear() {
if (isEmpty()) {
cout << "Queue is empty." << endl;
return;
}
cout << "Rear element is : " << queue[rear] << endl;
}
template <class T>
void LinerQueue<T>::Push(T item) {
if ((rear + 1) % length == front) {
cout << "Queue is full." << endl;
return;
}
rear = (rear + 1) % length;
queue[rear] = item;
}
template <class T>
void LinerQueue<T>::Pop() {
if (isEmpty()) {
cout << "Queue is empty." << endl;
return;
}
front = (front + 1) % length;
}
(3)main.cpp
#include"linerQueue.h"
#include"linerQueue.cpp"
using namespace std;
int main() {
LinerQueue<int> que(10);
for (int i = 0; i < 4; i++) {
que.Push(i);
}
cout << "---------- Push elements 0, 1, 2, 3. ----------" << endl;
que.Front();
que.Rear();
que.Pop();
que.Pop();
que.Pop();
que.Pop();
cout << "---------- Pop emements 0, 1, 2, 3. ----------" << endl;
que.Front();
que.Rear();
que.Push(10);
cout << "---------- Push element 10. ----------" << endl;
que.Front();
que.Rear();
system("pause");
return 0;
}
3. 链式队列
1. 概念
二叉树是每个结点最多有两个子树的树结构。
特点:
(1)有唯一的根节点;
(2)每一个左子树或右子树同时也是二叉树。
完全二叉树
设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布。
满二叉树
深度为k,且有2^k-1个结点的二叉树,称为满二叉树。这种树的特点是每一层上的结点数都是最大结点数。满二叉树是完全二叉树的特例。
2. 实现
3. 遍历
(1)递归实现
void preOrderTraverse1(TreeNode root) {
if (root != NULL) {
cout << root.val << " " ;
preOrderTraverse1(root.left);
preOrderTraverse1(root.right);
}
}
(2)非递归实现
void preOrderTraverse2(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
TreeNode pNode = root;
while (pNode != NULL || !stack.isEmpty()) {
if (pNode != NULL) {
cout << pNode.val << " " ;
stack.push(pNode);
pNode = pNode.left;
} else { //pNode == null && !stack.isEmpty()
TreeNode node = stack.pop();
pNode = node.right;
}
}
}
(1)递归实现
public void inOrderTraverse1(TreeNode root) {
if (root != NULL) {
inOrderTraverse1(root.left);
cout << root.val << " " ;
inOrderTraverse1(root.right);
}
}
(2)非递归实现
(1)递归实现
void postOrderTraverse1(TreeNode root) {
if (root != NULL) {
postOrderTraverse1(root.left);
postOrderTraverse1(root.right);
cout << root.val << " " ;
}
}
(2)非递归实现
(1)递归实现
(2)非递归实现