上学时写了一半的代码,留着吧。
复习书本:张宪超 《数据结构、算法及应用》
第一章、绪论
1.结构的分类
线性结构、树形结构、图结构
2.数据的存储结构
顺序方法-数组(访问优势)
链接方法-链表(修改优势)
索引方法-顺序存储的推广(提高检索效率,存储的是指向目标的指针)
散列方法-索引法的推广
3.渐进分析
4.时间复杂度分析,最好、最坏和平均情况(概率*花销的累加和)
5.空间开销
第二章、线性表
1.线性表的存储结构-[顺序表(数组,定长),链式存储结构(链表)]
2.线性表的运算-[创建实例,析构函数,增删改查,辅助操作]
3.行优先顺序表,列优先顺序表
4.单链表,双链表,循环链表
5.顺序栈,链式栈
6.顺序队列,链式队列
7.字符串~~(未写)~~
8.
第三章、数
1.概念
树有n个节点,n为0称为空结构/空树
兄弟节点:有共同父节点
叶子节点:无子节点
分支节点:非叶子结点
结点的度:孩子结点的数量
树的度:所有结点度的最大值
结点的层数:根节点的层数为0
树的深度:结点层数的最大值
数的高度:树的深度加1
有序树,无序树,森林
2.性质及表示方法
n结点度为m的树,最小高度为 上取整(lg(n(m-1)+1) / lg(m))
树形表示法,文氏图表示法,凹入标表示法,嵌套括号表示法
3.二叉树相关概念
所有结点度小于等于2为二叉树(空树也为二叉树)
完全二叉树:除最后一层外所有层结点达到最大值(叶子结点只能在最后一层和次大两层出现)
对于任意二叉树,度数为0的结点比度数
为2的结点多一个
4.二叉树的遍历
1)广度优先遍历。使用队列储存节点。队列头部节点寻找子节点并放到队列结尾。
2)前序遍历(先根遍历) 先访问根节点,将该节点右节点压入栈中,遍历左子树,重复过程,直到无左子树。弹出栈顶,继续遍历。
3)中序遍历(中根遍历) 将根节点压入栈中,并不断将根节点的左子节点压入栈中,直到没有左子节点。弹出栈顶并访问该节点,然后将该节点的右子节点压入栈,重复上面过程。
4)后序遍历(后根遍历) 从根节点向左搜索并压入栈中,直到没有节点。读取栈顶节点,如果没有右节点或者右节点访问过,就访问栈顶节点并弹出,否则将右节点压入栈中,并重复上面过程。
单链表(有头结点)
#include<iostream>
using namespace std;
template<class T>
class LinkNode{
public :
T data;
LinkNode<T>*link;
};
template<class T>
class LinkList{
private:
LinkNode<T>*head, *tail;
LinkNode<T>*currPtr;
int size;
public:
LinkList();
~LinkList();
int getSize()const;
bool isEmpty()const;
void insertTail(T &item);
T deleteHead();
void clear();
void show();
T getHeadValue();
void swapNext(LinkNode<T>*current, LinkNode<T>*father);
LinkNode<T>*getHeadLink();
};
template<class T>
LinkNode<T>* LinkList<T>::getHeadLink(){
return head;
}
template<class T>
void LinkList<T>::swapNext(LinkNode<T>*current,LinkNode<T>*father){
LinkNode<T>*next = current->link;
if (next == NULL)return;
LinkNode<T>*end = next->link;
father->link = next;
next->link = current;
current->link = end;
}
template<class T>
LinkList<T>::~LinkList(){
clear();
}
template<class T>
void LinkList<T>::clear(){
LinkNode<T>*temp = head->link;
while (temp != NULL){
LinkNode<T>*next = temp->link;
LinkNode<T>*now = temp;
delete now;
temp = next;
}
head->link = NULL;
tail = head;
size = 0;
}
template<class T>
T LinkList<T>::deleteHead(){
if (head->link == NULL){
cout << "error" << endl;
return 0;
}
LinkNode<T>*temp = head->link;
head->link = temp->link;
if (tail == temp){
tail = head;
}
size--;
T res = temp->data;
delete temp;
return res;
}
template<class T>
bool LinkList<T>::isEmpty()const{
return (size > 0 ? false : true);
}
template<class T>
int LinkList<T>::getSize()const{
return size;
}
template<class T>
void LinkList<T>::insertTail(T &item){
size++;
LinkNode<T>* node = new LinkNode<T>();
node->data = item; node->link = NULL;
tail->link = node;
tail = tail->link;
}
template<class T>
void LinkList<T>::show(){
LinkNode<T>*temp = head->link;
while (temp != NULL){
cout << temp->data << " ";
temp = temp->link;
}
}
template<class T>
T LinkList<T>::getHeadValue(){
return head->link->data;
}
template<class T>
LinkList<T>::LinkList(){
LinkNode<T> *headNode = new LinkNode<T>();
headNode->link = NULL;
head = tail = headNode;
size = 0;
}
int main(){
LinkList<int> s;
int n = 1;
for (int i = 0; i < n; i++){
int temp;
cin >> temp;
s.insertTail(temp);
}
LinkNode<int> *link = s.getHeadLink();
s.swapNext(link->link, link);
cout << s.isEmpty() << endl;
cout << s.getSize() << endl;
s.show();
s.clear();
s.deleteHead();
}
双链表(有头结点)
#include<iostream>
using namespace std;
template<class T>
class Node{
public:
T data;
Node<T>*next, *before;
Node(){
next = before = NULL;
}
};
template<class T>
class List{
private:
Node<T>*head, *tail;
int size;
public:
List();
~List();
int getSize();
void insert(int pos,T&item);
void show();
void deletePos(int pos);
int findPos(T&item);
};
template<class T>
int List<T>::getSize(){
return size;
}
template<class T>
List<T>::List(){
Node<T>*node = new Node<T>();
head = tail = node;
size = 0;
}
template<class T>
void List<T>::insert(int pos,T&item){
if (pos > size)return;
Node<T>*temp = head;
for (int curr = 0; curr < pos; curr++){
temp = temp->next;
}
Node<T>*last = new Node<T>();
last->data = item; last->before = temp; last->next = temp->next;
temp->next = last;
if (pos == size){
tail = last;
size++;
return;
}
size++;
last->next->before = last;
}
template<class T>
void List<T>::show(){
Node<T>*temp = head->next;
while (temp != NULL){
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
template<class T>
void List<T>::deletePos(int pos){
if (pos > size)return;
Node<T>*temp = head;
for (int curr = 0; curr < pos; curr++){
temp = temp->next;
}
Node<T>*now = temp->next;
temp->next = now->next;
if (pos < size-1){
now->next->before = temp;
}
delete now;
size--;
}
template<class T>
int List<T>::findPos(T&item){
Node<T>*temp = head->next;
int position = 0;
while (temp != NULL){
if (temp->data == item)return position;
temp = temp->next;
position++;
}
return -1;
}
template<class T>
List<T>::~List(){
int position = 0;
while (position < size){
deletePos(position);
position++;
}
}
int main(){
int n;
cin >> n;
List<int> s;
for (int i = 0; i < n; i++){
int temp;
cin >> temp;
s.insert(s.getSize(),temp);
}
s.show();
int p = 10;
s.insert(0, p);
s.show();
s.deletePos(1);
s.show();
int m = 23;
cout << s.findPos(m) << endl;
return 0;
}
####循环双链表
#include<iostream>
using namespace std;
template<class T>
class Node{
public:
T data;
Node<T>*next, *before;
Node(){
next = before = NULL;
}
};
template<class T>
class List{
private:
Node<T>*head, *tail;
int size;
public:
List();
~List();
int getSize();
void insert(int pos, T&item);
void show();
void deletePos(int pos);
int findPos(T&item);
};
template<class T>
int List<T>::getSize(){
return size;
}
template<class T>
List<T>::List(){
Node<T>*node = new Node<T>();
head = tail = node;
node->next = node->before = node;
size = 0;
}
template<class T>
void List<T>::insert(int pos, T&item){
if (pos > size)return;
Node<T>*temp = head;
for (int curr = 0; curr < pos; curr++){
temp = temp->next;
}
Node<T>*last = new Node<T>();
last->data = item; last->before = temp; last->next = temp->next;
temp->next = last;
if (pos == size){
tail = last;
size++;
return;
}
size++;
last->next->before = last;
}
template<class T>
void List<T>::show(){
Node<T>*temp = head->next;
while (temp != head){
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
template<class T>
void List<T>::deletePos(int pos){
if (pos > size)return;
Node<T>*temp = head;
for (int curr = 0; curr < pos; curr++){
temp = temp->next;
}
Node<T>*now = temp->next;
temp->next = now->next;
now->next->before = temp;
delete now;
size--;
}
template<class T>
int List<T>::findPos(T&item){
Node<T>*temp = head->next;
int position = 0;
while (temp != head){
if (temp->data == item)return position;
temp = temp->next;
position++;
}
return -1;
}
template<class T>
List<T>::~List(){
int position = 0;
while (position < size){
deletePos(position);
position++;
}
}
int main(){
int n;
cin >> n;
List<int> s;
for (int i = 0; i < n; i++){
int temp;
cin >> temp;
s.insert(s.getSize(), temp);
}
s.show();
int p = 10;
s.insert(0, p);
s.show();
s.deletePos(0);
s.show();
int m = 23;
cout << s.findPos(m) << endl;
return 0;
}
顺序栈
#include<iostream>
using namespace std;
template<class T>
class Stack{
public:
void clear();
bool push(T&item);
bool pop(T&item);
bool getTop(T&item);
bool isEmpty();
};
template<class T>
class arrStack:public Stack<T>{
private:
int maxSize;
int top;
T *st;
public:
arrStack(int size){
top = -1;
maxSize = size;
st = new T[maxSize];
}
~arrStack(){
delete[] st;
}
bool push(T&item){
if (top + 1 == maxSize)return false;
top++;
st[top] = item;
return true;
}
bool pop(T&item){
if (top == -1)return false;
item = st[top--];
return true;
}
bool getTop(T&item){
if (top == -1)return false;
item = st[top];
return true;
}
void clear(){
top = -1;
}
bool isEmpty(){
return (top == -1);
}
void show(){
int temp = 0;
while (temp <= top){
cout << st[temp++] << " ";
}
cout << endl;
}
};
int main(){
arrStack<int> *str = new arrStack<int>(10);
int n;
cin >> n;
int arr[10];
for (int i = 0; i < n; i++){
cin >> arr[i];
str->push(arr[i]);
}
int temp = -1;
str->show();
str->pop(temp);
str->show();
cout << temp << endl;
str->getTop(temp);
cout << temp;
str->clear();
str->show();
cout<<str->isEmpty();
}
链式栈
#include<iostream>
using namespace std;
template<class T>
class Stack{
public:
void pop();
T getTop();
void push(T item);
void show();
void clear();
};
template<class T>
class Node{
public:
T data;
Node<T>*next;
Node(){ next = NULL; }
};
template<class T>
class linkStack :public Stack<T>{
private:
Node<T>*head, *tail;
public:
linkStack(){
head = tail = NULL;
}
void push(T item){
Node<T>*node = new Node<T>();
node->next = head; node->data = item;
head = node;
if (head == NULL){
tail = node;
}
}
void show(){
Node<T>*node = head;
while (node != NULL){
cout << node->data << " ";
node = node->next;
}
cout << endl;
}
void clear(){
Node<T>*node = head;
while (node != NULL){
Node<T>*Next = node->next;
delete node;
node = Next;
}
head = tail = NULL;
}
void pop(){
if (head == NULL)return;
Node<T>*node = head;
head = head->next;
delete node;
}
T getTop(){
if (head == NULL)return 0;
return head->data;
}
};
int main(){
int n;
cin >> n;
linkStack<int>*s = new linkStack<int>();
s->show();
for (int i = 0; i < n; i++){
int temp;
cin >> temp;
s->push(temp);
}
s->show();
s->pop();
s->show();
cout << s->getTop() << endl;
s->clear();
s->show();
}
求字符串的最长相同前后缀长度
#include<iostream>
using namespace std;
#define N 40
int F[N];
char *B;
// a b a a b b a b a c
// 0 0 1 1 2 0 1 2 3
void getLongest(){
//Fi为0到i串的最长相同前后缀长度
F[0] = 0;
for (int i = 1; i < strlen(B); i++){
//获取第i位前的字符串的先后缀长度
int len = F[i - 1];
//找到加上新字符后的能构成最长前后缀的长度
while ((B[len] != B[i]) && (len>0)){
len = F[len - 1];
}
//找到
if (B[len] == B[i])F[i] = len + 1;
else F[len] = 0;
}
}
int main(){
A = new char[N];
B = new char[N];
cin >> B;
getLongest();
for (int i = 0; i < strlen(B); i++){
cout << F[i] << " ";
}
}
二叉树先中后序遍历,栈式和递归式及广度优先
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
#define lson (rt<<1|1)
#define rson ((rt+1)<<1)
#define N 100
int arr[N];
void buildTree(int n){
//15 1 2 3 0 4 0 5 0 0 6 7 0 0 0 8
for (int i = 0; i < n; i++){
cin >> arr[i];
}
}
void bfsShow(int n){
int rt = 0;
queue<int> q;
q.push(rt);
while (!q.empty()){
rt = q.front(); q.pop();
if (arr[rt] == 0)continue;
cout << arr[rt] << " ";
q.push(lson);
q.push(rson);
}
cout << endl;
}
void dfsPreShow(int n,int rt){
if (arr[rt] == 0)return;
cout << arr[rt] << " ";
dfsPreShow(n, lson);
dfsPreShow(n, rson);
}
void dfsMidShow(int n, int rt){
if (arr[rt] == 0)return;
dfsMidShow(n, lson);
cout << arr[rt] << " ";
dfsMidShow(n, rson);
}
void dfsBackShow(int n, int rt){
if (arr[rt] == 0)return;
dfsBackShow(n, lson);
dfsBackShow(n, rson);
cout << arr[rt] << " ";
}
void StackPreShow(int n){
stack<int> s;
int rt = 0;
while (arr[rt]!=0 || !s.empty()){
if (arr[rt] != 0){
cout << arr[rt] << " ";
s.push(rson);
rt = lson;
}
else{
rt = s.top(); s.pop();
}
}
cout << endl;
}
void StackMidShow(int n){
stack<int>s;
int rt = 0;
while (arr[rt] != 0 || !s.empty()){
if (arr[rt] != 0){
s.push(rt);
rt = lson;
}
else{
rt = s.top(); s.pop();
cout << arr[rt] << " ";
rt = rson;
}
}
}
void StackBackShow(int n){
int par = -1;
int rt = 0;
stack<int>s;
while (1){
while (arr[lson] != 0){
s.push(rt);
par = rt;
rt = lson;
}
//没有右节点或者访问过右节点,
//输出当前值,根变到栈顶,弹出栈顶
//当前根为栈顶的左子点
while (arr[rson] == 0 || par == rt * 2 + 2){
cout << arr[rt] << " ";
if (s.empty())return;
par = rt;
rt = s.top();
s.pop();
}
s.push(rt);
rt = rson;
}
}
int main(){
int n;
cin >> n;
buildTree(n);
bfsShow(n);
cout << endl;
dfsPreShow(n, 0); cout << endl;
StackPreShow(n); cout << endl;
dfsMidShow(n, 0); cout << endl;
StackMidShow(n); cout << endl;
dfsBackShow(n, 0); cout << endl;
StackBackShow(n); cout << endl;
}
先序建立的二叉搜索树
一种是插入方法,沿着根比大小
一种直接找左右节点
####平衡二叉树建树、删除、插入、查找
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
/*
*平衡二叉树插入、删除、查找
*
*
*
*/
class node{
public:
int val;
int h, bf;
node*left, *right;
node(int x){ val = x; left = right = NULL; h = 1; bf = 0; }
void copyVal(node*t){
this->val = t->val;
}
};
class tree{
public:
node*root;
stack<node*>s;
tree(){ root = NULL; }
int getH(node*rt){
if (rt == NULL)return 0;
int lh, rh;
lh = rh = 0;
if (rt->left)lh = rt->left->h;
if (rt->right)rh = rt->right->h;
return max(lh, rh) + 1;
}
int getBf(node*rt){
if (rt == NULL)return 0;
return getH(rt->right) - getH(rt->left);
}
node* RRrotate(node*rt){
node*right = rt->right;
rt->right = right->left;
right->left = rt;
rt->h = getH(rt);
rt->bf = getBf(rt);
right->h = getH(right);
right->bf = getBf(right);
return right;
}
node* LLrotate(node*rt){
node*left = rt->left;
rt->left = left->right;
left->right = rt;
rt->h = getH(rt);
rt->bf = getBf(rt);
left->h = getH(left);
left->bf = getBf(left);
return left;
}
node* LRrotate(node*rt){
node*l = rt->left;
rt->left = RRrotate(l);
return LLrotate(rt);
}
node* RLrotate(node*rt){
node*r = rt->right;
rt->right = LLrotate(r);
return RRrotate(rt);
}
node*insert(node*rt,int val){
if (rt == NULL){ return rt = new node(val); }
node*t = rt;
if (val < rt->val){
rt->left = insert(rt->left, val);
t = rt->left;
}
else{
rt->right = insert(rt->right, val);
t = t->right;
}
rt->h = getH(rt);
rt->bf = getBf(rt);
if (abs(rt->bf) <= 1)return rt;
else
if (rt->bf == 2 && t->bf == 1)return RRrotate(rt);
else if (rt->bf == 2 && t->bf == -1)return RLrotate(rt);
else if (rt->bf == -2 &&t->bf == -1)return LLrotate(rt);
else return LRrotate(rt);
}
void BFSshow(){
if (root == NULL){
cout << "empty" << endl;
}
queue<node*>q;
q.push(root);
while (!q.empty()){
node*t = q.front(); q.pop();
if (t->left)q.push(t->left);
if (t->right)q.push(t->right);
cout << t->val << " ";
}
cout << endl;
}
void preOrder(){
stack<node*>s;
node*t = root;
while (t || !s.empty()){
if (t){
cout << t->val << " ";
s.push(t->right);
t = t->left;
}
else{
t = s.top(); s.pop();
}
}
cout << endl;
}
void InOrder(){
stack<node*>s;
node*t = root;
while (t || !s.empty()){
if (t){
s.push(t);
t = t->left;
}
else{
t = s.top(); s.pop();
cout << t->val << " ";
t = t->right;
}
}
cout << endl;
}
void bacOrder(){
stack<node*>s;
node*pre = NULL;
node*t = root;
while (t){
while (t->left){
s.push(t);
pre = t;
t = t->left;
}
while (t->right == NULL || pre == t->right){
cout << t->val << " ";
pre = t;
if (s.empty()){
cout << endl;
return;
}
t = s.top(); s.pop();
}
s.push(t);
t = t->right;
}
cout << endl;
}
node*&find(int val){
node*t = root;
while (t){
if (val < t->val){
if (t->left&&t->left->val == val)return t->left;
else t = t->left;
}
else if (val>t->val){
if (t->right&&t->right->val == val)return t->right;
else t = t->right;
}
else return t;
}
t = NULL;
return t;
}
void build(){
int arr[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
for (int i = 0; i < sizeof(arr)/sizeof(int); i++){
root=insert(root,arr[i]);
}
BFSshow();
}
void combineDel(int val){
node*&t = find(val);
if (t == NULL)return;
if (t->left == NULL&&t->right == NULL){
delete t;
t = NULL;
}
else if (t->left == NULL&&t->right != NULL){
delete t;
t = t->right;
}
else if (t->right == NULL&&t->left){
delete t;
t = t->left;
}
else{
node*p = t->left;
node*pt = p;
node*par = t;
while (p->right){
par = p;
p = p->right;
}
if (par == t){
p->right = t->right;
delete t;
t->left = p;
}
else{
p->right = t->right;
delete t;
t = pt;
}
}
}
void copyDel(int val){
node*&t = find(val);
node*par = t;
if (t == NULL)return;
if (t->left == NULL&&t->right == NULL){
delete t;
t = NULL;
}
else if (t->left == NULL&&t->right != NULL){
delete t;
t = t->right;
}
else if (t->right == NULL&&t->left){
delete t;
t = t->left;
}
else{
node*p = t->left;
while (p->right){
par = p;
p = p->right;
}
t->copyVal(p);
delete p;
if (par == t)t->left = NULL;
else{
par->right = NULL;
}
}
}
void Del(node*&rt,int val){
if (rt->val == val){
node*t = rt;
if (t->left==NULL){
rt = rt->right;
if (rt){
rt->bf = getBf(rt);
rt->h = getH(rt);
}
delete t;
}
else if (t->right == NULL){
rt = rt->left;
if (rt){
rt->bf = getBf(rt);
rt->h = getH(rt);
}
delete t;
}
else{
node*lt = t->left;
node*par = t;
while (lt->right){
par = lt;
lt = lt->right;
}
rt->val = lt->val;
if (rt->bf == 0){
Del(rt->left, lt->val);
rt->bf = getBf(rt);
rt->h = getH(rt);
}
else if (rt->bf == 1){
Del(rt->left, lt->val);
rt = RRrotate(rt);
}
else if (rt->bf == -1){
Del(rt->left, lt->val);
if (rt->left->bf <=0){
rt = LLrotate(rt);
}
else {
rt = LRrotate(rt);
}
}
}
}
else if (val < rt->val){
Del(rt->left, val);
}
else{
Del(rt->right, val);
}
}
};
int main(){
tree t;
t.build();
t.Del(t.root,15);
t.preOrder();
t.InOrder();
}