零.时间复杂度分析
1.时间复杂度概念
什么是时间复杂度
时间复杂度是一个函数,它定性描述该算法的运行时间。
什么是大O
算法导论给出的解释:大O用来表示上界的,当用它作为算法的最坏情况运行时间的上界,就是对任意数据输入的运行时间的上界。
但是业内的一个默认规定,这里说的O代表的就是一般情况,而不是严格的上界。
面试中说道算法的时间复杂度是多少指的都是一般情况
为什么时间复杂度都是省略常数项系数?
因为大O就是数据量级突破一个点且数据量级非常大的情况下所表现出的时间复杂度,这个数据量也就是常数项系数已经不起决定性作用的数据量。
所以我们说的时间复杂度都是省略常数项系数的,是因为一般情况下都是默认数据规模足够的大,基于这样的事实,给出的算法时间复杂的的一个排行如下所示:
O(1)常数阶 < O(logn)对数阶 < O(n)线性阶 < O(n^2)平方阶 < O(n^3)立方阶 < O(2^n)指数阶
2.时间复杂度的化简
我们计算时间复杂度的时候往往是一个复杂的表达式,如下
O(2*n^2 + 10*n + 1000)
其实两步我们就可以化简完毕
①去掉常数项以及常数系数
O(n^2 + n)
②只保留最高项
O(n^2)
这样就是我们最后要的结果了。
3.常见排序算法时间复杂度分析
排序算法 | 时间复杂度 | 是否稳定 |
---|
直接插入排序,折半插入排序 | O(n^2) | 稳定 | 希尔排序 | O(n*(logn)^2) | 不稳定 | 起泡排序 | O(n^2) | 稳定 | 快速排序 | O(nlogn) | 不稳定 | 简单选择排序 | O(n^2) | 不稳定 | 堆排序 | O(nlogn) | 不稳定 | 归并排序 | O(nlogn) | 稳定 | 基数排序 | O(n) | 稳定 |
一.线性表
1.顺序表
#include <iostream>
#include<stdio.h>
using namespace std;
typedef int ElemType;
#define OK 1
#define ERROR 0
typedef int Status;
class SqList {
private:
int MaxSize;
int size;
ElemType* list;
public:
SqList();
~SqList();
int listSize();
Status listInit(int n);
Status listInsert(int i, ElemType s);
Status multiInsert(int i, int n, ElemType* item);
Status multiDel(int i, int n);
Status listDel(int i);
Status listGet(int i);
SqList listCombine(SqList& a, SqList& b);
ElemType* getListArr();
void listMove(int d, int n);
void listSort();
void ClearList();
void display();
};
SqList::SqList() {
size = 0;
MaxSize = 99;
list = new int[MaxSize];
}
SqList::~SqList() {
}
int SqList::listSize() {
return size;
}
Status SqList::listInit(int n) {
for (int i = 0; i < n; i++)
{
cin >> list[i];
}
size = n;
return OK;
}
Status SqList::listInsert(int i, ElemType s) {
if ((i > 0) && (i <= (size + 1)))
{
for (int k = size; k >= i; k--)
{
list[k] = list[k - 1];
}
list[i - 1] = s;
size++;
display();
return OK;
}
else {
cout << "error" << endl;
return ERROR;
}
}
Status SqList::multiInsert(int i, int n, ElemType* item) {
if ((i > 0) && (i <= (size + 1)))
{
for (int k = size; k >= i; k--)
{
list[k+n-1] = list[k - 1];
}
for (int k =i-1,flag=0; flag < n; k++,flag++)
{
list[k] = item[flag];
}
size+=n;
return OK;
}
else {
cout << "error" << endl;
return ERROR;
}
}
Status SqList::listDel(int i) {
if ((i > 0) && (i <= (size)))
{
for (int k = i-1; k <size; k++)
{
list[k] = list[k + 1];
}
size--;
display();
return OK;
}
cout << "error" << endl;
return ERROR;
}
Status SqList::multiDel(int i,int n) {
if ((i > 0) && (i <= size))
{
size -= n;
for (int k = i - 1; k < size; k++)
{
list[k] = list[k + n];
}
display();
return OK;
}
cout << "error" << endl;
return ERROR;
}
Status SqList::listGet(int i)
{
if ((i > 0) && (i <= size)) {
cout << list[i - 1] << endl;
return OK;
}
cout << "error" << endl;
return ERROR;
}
void SqList::ClearList() {
size = 0;
}
void SqList::display() {
if (size == 0)
cout << "当前为空表!!!" << endl;
else
{
for (int i = 0; i < size ; i++)
{
cout << list[i] << " ";
}
cout << endl;
}
}
void SqList::listSort()
{
for (int i = 0; i < size - 1; i++)
{
for (int i = 0; i < size - 1; i++)
{
if (list[i] > list[i + 1])
{
int temp;
temp = list[i];
list[i] = list[i + 1];
list[i + 1] = temp;
}
}
}
}
ElemType* SqList::getListArr() {
return list;
}
void SqList::listMove(int d, int n)
{
int* temp = new int[size];
if (d == 0)
{
for (int i = 0; i < size; i++)
{
temp[(size - (n - i)) % size] = list[i];
}
}
else if (d == 1)
{
for (int i = 0; i < size; i++)
{
temp[(size + (i + n)) % size] = list[i];
}
}
list = temp;
}
SqList SqList::listCombine(SqList& a, SqList& b)
{
SqList res1;
res1.multiInsert(1, a.listSize(), a.getListArr());
res1.multiInsert(2, b.listSize(), b.getListArr());
res1.listSort();
res1.display();
return res1;
}
int main()
{
SqList test1;
int n1,a,b;
cin >> n1;
test1.listInit(n1);
test1.display();
cin >> a >> b;
test1.listMove(a, b);
test1.display();
cin >> a >> b;
test1.listMove(a, b);
test1.display();
return 0;
}
2.单链表
#include<stdio.h>
#include<iostream>
using namespace std;
typedef int ElemType;
#define OK 1
#define ERROR 0
typedef int Status;
class Node {
public:
ElemType data;
Node* next;
Node() {
next = NULL;
data = 0;
}
};
class LinkList {
public:
Node* head;
int len;
LinkList();
~LinkList();
Node* GetIndex(int i);
Status Swap(int pa,int pb);
Status GetElem(int i);
Status ListInsert(int i, ElemType e);
Status ListElemDelete(int i);
void CreatListHead(ElemType e);
void CreatListTail(ElemType e);
Status ClearList();
void display();
LinkList merge(LinkList& La, LinkList& Lb);
void sort();
};
LinkList::LinkList() {
head = new Node;
len = 0;
}
LinkList::~LinkList() {
}
void LinkList::sort() {
for (int i = 1; i <= len; i++)
{
for (int k = i; k <= len; k++)
{
if (GetIndex(i+1)->data > GetIndex(k+1)->data)
{
Swap(i, k);
}
}
}
}
LinkList LinkList::merge(LinkList& La, LinkList& Lb) {
LinkList res;
Node* p = La.head;
for (int i = 1; i <= La.len; i++)
{
p = p->next;
res.ListInsert(i, p->data);
}
p = Lb.head;
for (int i = 1; i <= Lb.len; i++)
{
p = p->next;
res.ListInsert(i, p->data);
}
res.sort();
return res;
}
Node* LinkList::GetIndex(int i) {
int j = 1;
Node* p;
p = head;
while (p && j < i)
{
p = p->next;
++j;
}
if (!p || j > i || i == 0) {
return NULL;
}
else return p;
}
Status LinkList::Swap(int pa, int pb) {
if (pa < 1 || pb<1 || pa>len || pb>len)
return ERROR;
Node* p1 = GetIndex(pa);
Node* p2 = GetIndex(pb);
Node* temp = p1->next;
p1->next = p2->next;
p2->next = temp;
temp = p1->next->next;
p1->next->next = p2->next->next;
p2->next->next = temp;
return OK;
}
Status LinkList::GetElem(int i) {
int j = 0;
Node* p;
p = head;
while (p && j < i)
{
p = p->next;
++j;
}
if (!p || j > i || i == 0) {
cout << "error" ;
return ERROR;
}
cout << p->data << " ";
return OK;
}
Status LinkList::ListInsert(int i, ElemType e) {
int j;
j = 1;
Node* p, * s;
p = head;
while (p->next != nullptr && j < i) {
p = p->next;
++j;
}
if (!p || j < i || i == 0) {
cout << "error" << endl;
return ERROR;
}
s = new Node;
s->data = e;
s->next = p->next;
p->next = s;
len++;
return OK;
}
Status LinkList::ListElemDelete(int i) {
int j;
Node* p, * q;
p = head;
j = 1;
while (p->next && j < i)
{
p = p->next;
++j;
}
if (!(p->next) || j >i||i==0) {
cout << "error" << endl;
return ERROR;
}
q = p->next;
p->next = q->next;
delete q;
len--;
return OK;
}
void LinkList::CreatListHead(ElemType e) {
Node* p;
p = new Node;
p->data = e;
p->next = head->next;
head->next = p;
len++;
}
void LinkList::CreatListTail(ElemType e) {
Node* p, * node;
p = new Node;
p = head;
node = new Node;
int j = 0;
while (p->next && j < len)
{
p = p->next;
++j;
}
node->data = e;
node->next = NULL;
p->next = node;
len++;
}
Status LinkList::ClearList() {
Node* p, * q;
p = head->next;
while (p)
{
q = p->next;
delete p;
p = q;
}
head->next = NULL;
len = 0;
return OK;
}
void LinkList::display() {
for (int i = 0; i < len; i++)
{
GetElem(i + 1);
}
cout << endl;
}
int main() {
LinkList test1,test2;
int n;
ElemType data;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> data;
test1.ListInsert(i + 1, data);
}
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> data;
test2.ListInsert(i + 1, data);
}
LinkList res = test1.merge(test1, test2);
res.display();
return 0;
}
3.循环链表
#include<stdio.h>
#include<iostream>
using namespace std;
typedef int ElemType;
#define OK 1
#define ERROR 0
typedef int Status;
class Node {
public:
ElemType data;
Node* next;
Node() {
next = NULL;
data = 0;
}
};
class LinkList {
public:
Node* head;
Node* rear;
int len;
LinkList();
~LinkList();
Status GetElem(int i);
Status ListInsert(int i, ElemType e);
Node* GetElemIndex(int i);
Status ListElemDelete(int i);
void display();
};
LinkList::LinkList() {
head = new Node;
rear = new Node;
rear->next = head;
rear->data = head->data;
len = 0;
}
LinkList::~LinkList() {
}
Node* LinkList::GetElemIndex(int i) {
int j = 1;
Node* p;
p = head->next;
while (p != head && j < i)
{
p = p->next;
++j;
}
if (!p || j > i)
return ERROR;
return p;
}
Status LinkList::GetElem(int i) {
int j = 1;
Node* p;
p = head->next;
while (p!=head && j < i)
{
p = p->next;
++j;
}
if (!p || j > i)
return ERROR;
cout << p->data << endl;
return OK;
}
Status LinkList::ListInsert(int i, ElemType e) {
int j;
j = 1;
Node* p, * s;
p = head;
while (p->next != head && j < i) {
p = p->next;
++j;
}
if (!p || j > i)
return ERROR;
s = new Node;
s->data = e;
s->next = p->next;
p->next = s;
len++;
rear->data = GetElemIndex(len)->data;
return OK;
}
Status LinkList::ListElemDelete(int i) {
int j;
Node* p, * q;
p = head->next;
j = 1;
while (p->next != head && j < i-1)
{
p = p->next;
++j;
}
if (!p || j > i)
return ERROR;
q = p->next;
p->next = q->next;
delete q;
len--;
rear->data = GetElemIndex(len)->data;
return OK;
}
void LinkList::display() {
for (int i = 0; i < len; i++)
{
int k = GetElem(i + 1);
if (k == 0) {
cout << "display Error!";
}
}
}
int main() {
LinkList test;
int n;
ElemType data;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> data;
test.ListInsert(i + 1, data);
}
test.display();
cout << "尾结点数据域: "<<test.rear->data << endl;
cout << "头结点数据域: "<<test.rear->next->data << endl;
cout << "第一个结点数据域: "<<test.rear->next->next->data << endl;
return 0;
}
4.双向链表
#include<iostream>
using namespace std;
class ListNode
{
public:
ListNode* front;
int data;
ListNode* next;
ListNode()
{
front = this;
next = this;
data = NULL;
}
};
class LinkList
{
public:
ListNode* head;
int len;
LinkList();
void LL_add(int x);
ListNode* LL_index(int i);
void LL_insert(int i, int item);
void LL_del(int i);
void LL_display();
void disPlayFB(int i);
};
LinkList::LinkList()
{
head = new ListNode();
len = 0;
}
void LinkList::LL_add(int x)
{
ListNode* l = new ListNode();
l->data = x;
l->next = head;
if (head->next == head)
{
l->front = head;
head->next = l;
head->front = l;
}
else
{
l->front = LL_index(len);
LL_index(len)->next = l;
head->front = l;
}
len++;
}
ListNode* LinkList::LL_index(int i)
{
if ((i <= 0) || (i > len))
{
cout << "index_error" << endl;
}
else
{
ListNode* p;
p = head;
for (int k = 1; k <= i; k++)
{
p = p->next;
}
return p;
}
}
void LinkList::LL_insert(int i, int item)
{
i = i - 1;
if (i == len)
{
LL_add(item);
}
else if (i == 1)
{
if (len == 0)
{
LL_add(item);
}
else
{
ListNode* l = new ListNode();
l->data = item;
l->front = head;
l->next = LL_index(1);
LL_index(1)->front = l;
head->next = l;
len++;
}
}
else
{
ListNode* l = new ListNode();
l->data = item;
l->next = LL_index(i);
LL_index(i)->front = l;
LL_index(i - 1)->next = l;
l->front = LL_index(i - 1);
len++;
}
}
void LinkList::LL_del(int i)
{
if ((i <= 0) || (i > len))
{
cout << "del_error" << endl;
}
else
{
if (i == 1)
{
if (len == 1)
{
head->next = head;
head->front = head;
}
else
{
head->next = LL_index(2);
LL_index(2)->front = head;
}
}
else if (i == len)
{
LL_index(i - 1)->next = head;
head->front = LL_index(i - 1);
}
else
{
LL_index(i - 1)->next = LL_index(i + 1);
LL_index(i)->front = LL_index(i - 1);
}
len--;
}
}
void LinkList::LL_display()
{
ListNode* p;
p = head;
if (p->next == head)
{
cout << "-";
}
while (p->next != head)
{
p = p->next;
cout << p->data;
}
cout << endl;
}
void LinkList::disPlayFB(int i) {
ListNode* p;
p = head;
while (p->next != head)
{
p = p->next;
if (p->data == i) {
if (p->front->data)
cout << p->front->data << " ";
if (p->next != head)
cout << p->next->data << endl;
}
}
}
int main() {
LinkList test;
int n, m;
int temp1,temp2;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> temp1;
test.LL_insert(i,temp1);
}
while (m--)
{
cin >> temp2;
test.disPlayFB(temp2);
}
}
5.学生宿舍管理系统
#include <list>
#include <map>
#include<stdio.h>
#include<iostream>
using namespace std;
class student {
public:
string name;
int id;
student(string na, int i) {
name = na; id = i;
}
};
int main() {
list <student> stu;
list <int> empty;
list<int>::iterator i;
list<student>::iterator j;
map<int, int> hash;
int n, number;
cin >> n;
string name;
for (int i = 0; i < n; i++) {
cin >> name >> number;
stu.push_back(student(name, number));
hash[number]=1;
}
for (int i = 101; i <= 120; i++) {
if (!hash[i]) {
empty.push_back(i);
}
}
int m;
string sign;
cin >> m;
while (m--) {
cin >> sign;
if (sign == "assign") {
cin >> name;
int tmp = empty.front();
for (j = stu.begin(); j != stu.end(); ) {
if (j->id > tmp ) {
stu.insert(j, 1, student(name, tmp));
break;
}
if (++j == stu.end()) {
stu.insert(j, 1, student(name, tmp));
break;
}
}
empty.pop_front();
}
if (sign == "return") {
cin >> number;
for (j = stu.begin(); j != stu.end(); j++) {
if (j->id == number) {
stu.erase(j);
empty.push_back(number);
break;
}
}
}
if (sign == "display_used") {
for (j = stu.begin(); j != stu.end();) {
cout << j->name << "(" << j->id << ")";
if (++j != stu.end()) cout << "-";
}
cout << endl;
}
if (sign == "display_free") {
for (i = empty.begin(); i != empty.end();) {
cout << *i;
if (++i != empty.end()) cout << "-";
}
}
}
return 0;
}
6.多项式相加
#include<stdio.h>
#include<iostream>
using namespace std;
class Node {
public:
int coe;
int index;
Node* next;
Node() {
next = NULL;
coe = -1;
index = -1;
}
Node(int coe1,int index1) {
coe = coe1;
index = index1;
next = NULL;
}
};
class list
{
public:
Node* head;
int len;
list();
void pushBack(int coe1, int index1);
void disPlay();
void disPlayItem(int i);
};
list::list() {
head = new Node;
len = 0;
}
void list::pushBack(int coe1,int index1) {
Node* p, * node;
p = new Node;
p = head;
node = new Node(coe1, index1);
int j = 0;
while (p->next && j < len)
{
p = p->next;
++j;
}
p->next = node;
len++;
}
void list::disPlay() {
for (int i = 1; i <= len; i++)
{
disPlayItem(i);
}
}
void list::disPlayItem(int i) {
int j = 0;
Node* p;
p = head;
while (p && j < i)
{
p = p->next;
++j;
}
if (!p || j > i || i == 0) {
cout << "error";
}
if (p->coe != 0) {
if (p->coe > 0)
cout << p->coe;
else
cout << "(" << p->coe << ")";
if (p->index != 0)
{
if(p->index > 0)
cout << "x^" << p->index;
else
cout << "x^" << "(" << p->index << ")";
}
}
if (p->next)
cout << " + ";
else
cout << endl;
}
list add(list& L1, list& L2) {
Node* p1 = L1.head->next;
Node* p2 = L2.head->next;
list res;
while (p1 || p2) {
if ( p1 && p2 && (p1->index == p2->index))
{
int resCoe = p1->coe + p2->coe;
if(resCoe!=0)
res.pushBack(resCoe, p1->index);
p1 = p1->next;
p2 = p2->next;
}
else if ( p1 && p2 && p1->index > p2->index || !p1 )
{
res.pushBack(p2->coe, p2->index);
p2 = p2->next;
}
else if (p1 && p2 && p1->index < p2->index|| !p2 )
{
res.pushBack(p1->coe, p1->index);
p1 = p1->next;
}
}
return res;
}
int main() {
int t;
cin >> t;
while (t--) {
list L1, L2,res;
int n;
cin >> n;
int coe, index;
for (int i = 0; i < n; i++)
{
cin >> coe >> index;
L1.pushBack(coe, index);
}
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> coe >> index;
L2.pushBack(coe, index);
}
L1.disPlay();
L2.disPlay();
res = add(L1, L2);
res.disPlay();
}
return 0;
}
二.栈
1.顺序存储结构
#include <iostream>
#include<stdio.h>
using namespace std;
typedef int ElemType;
#define OK 1
#define ERROR 0
typedef int Status;
class SqStack {
private:
int MaxSize;
int top;
ElemType* list;
public:
SqStack();
~SqStack();
Status Push(ElemType e);
Status Pop(ElemType *e);
Status Pop();
Status GetTop(ElemType* e);
void ClearStack();
void display();
};
SqStack::SqStack() {
top = -1;
MaxSize = 99;
list = new int[MaxSize];
}
SqStack::~SqStack() {
delete[]list;
}
Status SqStack::Push(ElemType e) {
if (top == MaxSize - 1)
return ERROR;
top++;
list[top] = e;
return OK;
}
Status SqStack::Pop(ElemType *e) {
if (top == -1)
return ERROR;
*e = list[top];
top--;
return OK;
}
Status SqStack::Pop() {
if (top == -1)
return ERROR;
top--;
return OK;
}
Status SqStack::GetTop(ElemType* e) {
if (top == -1)
return ERROR;
*e = list[top];
return OK;
}
void SqStack::ClearStack() {
top = -1;
}
void SqStack::display() {
if (top == -1)
cout << "当前为空栈!!!" << endl;
else
{
cout << "当前栈内元素有:";
for (int i = 0; i < top + 1; i++)
{
cout << list[i] << " ";
}
cout << endl;
}
}
int main()
{
SqStack test;
test.Push(1);
test.display();
test.Push(2);
test.display();
test.Push(3);
test.display();
test.Pop();
test.display();
ElemType *topElem;
topElem = new ElemType;
test.GetTop(topElem);
cout << "栈顶元素为:" << *topElem << endl;
test.ClearStack();
test.display();
return 0;
}
2.双向循环链式存储结构
#include <iostream>
#include<stdio.h>
using namespace std;
typedef int ElemType;
#define OK 1
#define ERROR 0
typedef int Status;
class Node {
public:
ElemType data;
Node* next;
Node* front;
Node() {
next = NULL;
front = NULL;
data = 0;
}
};
class LinkStack {
private:
Node* top;
Node* bottom;
int len;
public:
LinkStack();
~LinkStack();
Status Push(ElemType e);
Status Pop(ElemType* e);
Status Pop();
Status StackEmpty();
Status GetTop(ElemType* e);
Status ClearStack();
void display();
};
LinkStack::LinkStack() {
top = new Node;
len = 0;
}
LinkStack::~LinkStack() {
Node* p, * q;
p = top;
for (int i = 0; i < len; i++)
{
q = p->next;
delete p;
p = q;
}
len = 0;
}
Status LinkStack::StackEmpty() {
if (len == 0)
return 1;
else
return 0;
}
Status LinkStack::Push(ElemType e) {
Node* temp;
temp = new Node;
temp->data = e;
temp->next = top;
top->front = temp;
top = temp;
if (len == 0) {
top->front = top;
bottom = top;
}
else
top->front = bottom;
len++;
return OK;
}
Status LinkStack::Pop(ElemType* e) {
if (StackEmpty())
return ERROR;
*e = top->data;
Node* temp;
temp = top;
top->front->next = top->next;
top->next->front = top->front;
top = temp->next;
delete temp;
len--;
return OK;
}
Status LinkStack::Pop() {
if (StackEmpty())
return ERROR;
Node* temp;
temp = top;
top->front->next = top->next;
top->next->front = top->front;
top = temp->next;
delete temp;
len--;
return OK;
}
Status LinkStack::GetTop(ElemType* e) {
if (StackEmpty())
return ERROR;
*e = top->data;
return OK;
}
Status LinkStack::ClearStack() {
Node* p, * q;
p = top->next;
for (int i = 0; i < len-1; i++)
{
q = p->next;
delete p;
p = q;
}
top->next = NULL;
top->front = NULL;
len = 0;
return OK;
}
void LinkStack::display() {
Node *temp;
if (StackEmpty())
cout << "当前为空栈!!!" << endl;
else
{
temp = top;
cout << "当前栈内元素有:";
for (int i = 0; i < len; i++)
{
cout << temp->front->data << " ";
temp = temp->front;
}
cout << endl;
}
}
int main()
{
LinkStack test;
test.Push(1);
test.display();
test.Push(2);
test.display();
test.Push(3);
test.display();
test.Pop();
test.display();
ElemType* topElem;
topElem = new ElemType;
test.GetTop(topElem);
cout << "栈顶元素为:" << *topElem << endl;
test.ClearStack();
test.display();
test.Push(1);
test.display();
test.ClearStack();
test.display();
return 0;
}
3.STL类模板实现
stack类使用的参考代码
- 1、包含头文件:
#include <stack> - 2、创建一个堆栈对象s(注意stack是模板类):stack s; //堆栈的数据类型是字符型
- 3、把一个字符ct压入堆栈:
s.push(ct) ; - 4、把栈顶元素弹出:
s.pop() ; - 5、获取栈顶元素,放入变量c2: c2 =
s.top() ; - 6、判断堆栈是否空:
s.empty() ,如果为空则函数返回true,如果不空则返回false - 7、对堆栈进行操作时,一定要记得查看堆栈是否为空
#include<iostream>
#include<stack>
#include<string>
using namespace std;
int main() {
stack<char> s;
int t;
string c;
cin >> t;
int len;
while (t--)
{
cin >> c;
len = c.size();
for (int i = 0; i < len; i++)
{
if (c[i] == '#' && !s.empty())
s.pop();
else if(c[i] != '#')
s.push(c[i]);
}
stack<char> ans;
while (!s.empty())
{
ans.push(s.top());
s.pop();
}
if (ans.empty())
cout << "NULL";
while (!ans.empty())
{
cout << ans.top();
ans.pop();
}
cout << endl;
}
return 0;
}
括号匹配
#include<iostream>
#include<stack>
#include<string>
using namespace std;
int main() {
int t;
cin >> t;
while (t--)
{
int temp=1;
stack<char> s;
string tt;
cin >> tt;
int len = tt.size();
for (int i = 0; i < len; i++)
{
temp = 1;
if (tt[i] == '(' || tt[i] == '[' || tt[i] == '{')
s.push(tt[i]);
else if (tt[i] == ')' ) {
if (s.empty()) {
temp = 0;
cout << "error" << endl;
break;
}
if(s.top() == '(')
s.pop();
else {
temp = 0;
cout << "error" << endl;
break;
}
}
else if (tt[i] == ']') {
if (s.empty()) {
temp = 0;
cout << "error" << endl;
break;
}
if (s.top() == '[')
s.pop();
else {
temp = 0;
cout << "error" << endl;
break;
}
}
else if (tt[i] == '}') {
if (s.empty()) {
temp = 0;
cout << "error" << endl;
break;
}
if (s.top() == '{')
s.pop();
else {
temp = 0;
cout << "error" << endl;
break;
}
}
}
if(!s.empty()&&temp==1)
cout << "error" << endl;
else if (temp == 1&&s.empty())
cout << "ok" << endl;
}
return 0;
}
迷宫求解
#include<iostream>
#include<stack>
using namespace std;
const int m = 999;
int Lu[m][m];
int n;
int path(int i, int j) {
if (j + 1 < n && !Lu[i][j + 1])
return 1;
else if (i + 1 < n && !Lu[i + 1][j])
return 2;
else if (j - 1 >= 0 && !Lu[i][j - 1])
return 3;
else if (i - 1 >= 0 && !Lu[i - 1][j])
return 4;
return 0;
}
int main() {
int t;
int ii[] = { 0, 0, 1, 0, -1 };
int jj[] = { 0, 1, 0, -1, 0 };
cin >> t;
while (t--) {
cin >> n;
stack<int> stx;
stack<int> sty;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> Lu[i][j];
int i = 0;
int j = 0;
if (Lu[0][0] == 0) {
Lu[0][0] = 1;
stx.push(0);
sty.push(0);
while (1) {
int k = path(i, j);
if (k) {
i += ii[k];
j += jj[k];
Lu[i][j] = 1;
stx.push(i);
sty.push(j);
}
else if (!stx.empty() && !sty.empty()) {
i = stx.top();
j = sty.top();
if (!path(i, j)) {
stx.pop();
sty.pop();
}
}
if ((stx.empty() && sty.empty()) || (i == n - 1 && j == n - 1))
break;
}
}
if (stx.empty() && sty.empty())
{
cout << "no path" << endl;
}
else {
int path[1000];
int len = 0;
int l = 0;
while (!stx.empty() && !sty.empty()) {
len += 2;
path[l++] = sty.top();
path[l++] = stx.top();
stx.pop();
sty.pop();
}
int flag = 1;
for (int i = len - 1; i >= 0;) {
cout << '[' << path[i--] << ',' << path[i--] << ']' << "--";
if ((flag++) % 4 == 0)
cout << endl;
}
cout << "END" << endl;
}
}
return 0;
}
波兰式,逆波兰式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZkdJEZI4-1656231405137)(数据结构/image-20220328000953008.png)]
- 注意字符char拼接成string的用法
傻逼OJ 行末尾不能有空格
#include<iostream>
#include<stack>
#include<string>
using namespace std;
stack<char> c1;
stack<string> c2;
void nP(string n) {
int len;
len = n.size();
char temp;
for (int i = 0; i < len; i++)
{
if (isdigit(n[i])) {
if ( i<(len-1)&&isdigit(n[i+1])) {
cout << n[i] ;
}
else
cout << n[i] << " ";
}
else if (n[i] == '+'|| n[i] == '-') {
if (!c1.empty()&&c1.top() == '*' || !c1.empty() && c1.top() == '/') {
while (!c1.empty()) {
cout << c1.top() << " ";
c1.pop();
}
c1.push(n[i]);
}
else
c1.push(n[i]);
}
else if (n[i] == '*'||n[i]=='/'|| n[i] == '(') {
c1.push(n[i]);
}
else if (n[i] == ')') {
temp = c1.top();
while (temp!='(')
{
cout << temp << " ";
c1.pop();
temp = c1.top();
}
c1.pop();
}
}
while (!c1.empty()) {
char temp = c1.top();
c1.pop();
if (c1.empty())
cout << temp;
else
cout << temp << " ";
}
cout << endl;
cout << endl;
}
void P(string n) {
int len;
len = n.size();
char temp;
for (int i = len-1; i >=0; i--)
{
if (isdigit(n[i])) {
if (i >0 && isdigit(n[i - 1])) {
string t = "";
t += n[i - 1];
t += n[i];
c2.push(t);
}
else if (i < (len - 1) && isdigit(n[i + 1]) ){
}
else {
string t = "";
t += n[i];
c2.push(t);
}
}
else if (n[i] == '+' || n[i] == '-') {
if (!c1.empty() && c1.top() == '*' || !c1.empty() && c1.top() == '/') {
while (!c1.empty()) {
string t = "";
t += c1.top();
c2.push(t);
c1.pop();
if (!c1.empty() && c1.top() == '+' || !c1.empty() && c1.top() == '-')
break;
}
c1.push(n[i]);
}
else
c1.push(n[i]);
}
else if (n[i] == '*' || n[i] == '/' || n[i] == ')') {
c1.push(n[i]);
}
else if (n[i] == '(') {
temp = c1.top();
while (temp != ')')
{
string t = "";
t += temp;
c2.push(t);
c1.pop();
temp = c1.top();
}
c1.pop();
}
}
while (!c1.empty()) {
string t = "";
t += c1.top();
c2.push(t);
c1.pop();
}
while (!c2.empty()) {
string temp = c2.top();
c2.pop();
if (c2.empty())
cout << temp;
else
cout << temp <<" ";
}
cout << endl;
}
int main() {
int t;
cin >> t;
string c;
while (t--)
{
cin >> c;
P(c);
nP(c);
}
return 0;
}
队列+堆栈–数制转换
#include <iostream>
#include <iomanip>
#include <queue>
#include <stack>
using namespace std;
int main()
{
double num;
int k, t;
cin >> t;
while (t--)
{
cin >> num >> k;
int zheng = num;
float xiao = num - zheng;
stack<char> res1;
queue<char> res2;
while (zheng)
{
int res = zheng % k;
zheng /= k;
if (res >= 10) {
res1.push(res + 'A' - 10);
}
else {
res1.push(res + '0');
}
}
int fix = 3;
while (fix--)
{
xiao *= k;
int zh = int(xiao);
if (xiao >= 10) {
res2.push(zh + 'A' - 10);
}
else {
res2.push(zh + '0');
}
xiao -= zh;
}
while (!res1.empty()) {
cout << res1.top();
res1.pop();
}
cout << ".";
while (!res2.empty()) {
cout << res2.front();
res2.pop();
}
cout << endl;
}
}
三.队列
1.循环顺序存储结构
#include <iostream>
#include<stdio.h>
using namespace std;
typedef int ElemType;
#define OK 1
#define ERROR 0
typedef int Status;
class SqQueue {
private:
int MaxSize;
int front;
int rear;
ElemType* list;
public:
SqQueue();
~SqQueue();
int QueueLength();
Status EnQueue(ElemType e);
Status Dequeue();
void ClearQueue();
void display();
};
SqQueue::SqQueue() {
front = 0;
rear = 0;
MaxSize = 99;
list = new int[MaxSize];
}
SqQueue::~SqQueue() {
delete[]list;
}
int SqQueue::QueueLength() {
return (rear - front + MaxSize) % MaxSize;
}
Status SqQueue::EnQueue(ElemType e) {
if ((rear + 1) % MaxSize == front)
return ERROR;
list[rear] = e;
rear = (rear + 1) % MaxSize;
return OK;
}
Status SqQueue::Dequeue() {
if (front == rear)
return ERROR;
front = (front + 1) % MaxSize;
return OK;
}
void SqQueue::ClearQueue() {
front = 0;
rear = 0;
}
void SqQueue::display() {
if (front == rear)
cout << "当前为空队列!!!" << endl;
else
{
cout << "当前队列内元素有(头---->尾):";
for (int i =front,j=0 ; j < QueueLength(); i++,j++)
{
cout << list[i%MaxSize] << " ";
}
cout << endl;
}
}
int main()
{
SqQueue test;
test.display();
test.EnQueue(2);
test.display();
test.EnQueue(3);
test.display();
test.EnQueue(4);
test.display();
test.Dequeue();
test.display();
test.ClearQueue();
test.display();
return 0;
}
2.链式存储结构
#include <iostream>
#include<stdio.h>
using namespace std;
typedef int ElemType;
#define OK 1
#define ERROR 0
typedef int Status;
class Node {
public:
ElemType data;
Node* next;
Node() {
next = NULL;
data = 0;
}
};
class LinkQueue {
private:
Node* front;
Node* rear;
int len;
public:
LinkQueue();
~LinkQueue();
Status EnQueue(ElemType e);
Status DeQueue();
Status ClearQueue();
void display();
};
LinkQueue::LinkQueue() {
front = new Node;
rear = front;
len = 0;
}
LinkQueue::~LinkQueue() {
Node* p, * q;
p = front;
for (int i = 0; i < len; i++)
{
q = p->next;
delete p;
p = q;
}
front->next = NULL;
rear = front;
len = 0;
}
Status LinkQueue::EnQueue(ElemType e) {
Node* temp = new Node;
temp->data = e;
temp->next = NULL;
rear->next = temp;
rear = temp;
len++;
return OK;
}
Status LinkQueue::DeQueue() {
Node *p = new Node;
if (front == rear)
return ERROR;
p = front->next;
front->next = p->next;
if (rear == p)
rear = front;
delete p;
len--;
return OK;
}
Status LinkQueue::ClearQueue() {
Node* p, * q;
p = front->next;
for (int i = 0; i < len-1; i++)
{
q = p->next;
delete p;
p = q;
}
front->next=NULL;
rear = front;
len = 0;
return OK;
}
void LinkQueue::display() {
Node* temp;
if (rear == front)
cout << "当前为空队列!!!" << endl;
else
{
temp = front;
cout << "当前对列内元素有:";
for (int i = 0; i < len; i++)
{
cout << temp->next->data << " ";
temp = temp->next;
}
cout << endl;
}
}
int main() {
LinkQueue test;
test.EnQueue(1);
test.EnQueue(2);
test.EnQueue(3);
test.display();
test.DeQueue();
test.display();
test.ClearQueue();
test.EnQueue(3);
test.EnQueue(1);
test.display();
test.ClearQueue();
test.display();
return 0;
}
3.STL类模板实现
队列queue的用法如下:
- 1.包含头文件:
#include <queue> - 2.定义一个整数队列对象:
queue<int> myQe ; - 3.定义一个整数队列对象数组:queue myQA[10];
- 4.入队操作:
myQe.push(itemp) ; //把整数itemp进入队列 - 5.出队操作:
myQe.pop() ; //把队头元素弹出队列,注意本操作不获取队头元素 - 6.获取队头元素: itemp =
myQe.front() ; // 把队头元素放入itemp中,注意本操作不弹出元素 - 7.判断队列是否为空:
myQe.empty() ;//队列空则返回true,不空则返回false
4.组队列(哈希表,队列)
#include <iostream>
#include <iomanip>
#include <queue>
#include <stack>
#include<string>
#include <map>
using namespace std;
int main()
{
int t;
cin >> t;
queue<int>*res=new queue<int>[t];
queue<int> Res;
map<int, int> group;
for (int i = 1; i <= t; i++)
{
int j;
cin >> j;
while (j--) {
int x;
cin >> x;
group[x] = i;
}
}
string operation;
cin >> operation;
int temp = 0;
while (operation!="STOP")
{
int num;
if (operation == "ENQUEUE") {
cin >> num;
for (int i = 0; i < t; i++)
{
if (res[i].empty() || group[res[i].front()] == group[num]) {
res[i].push(num);
break;
}
}
}
else if (operation == "DEQUEUE") {
for (int i = 0+temp; i < t; i++)
{
if (!res[i].empty()) {
cout << res[i].front() << " ";
res[i].pop();
break;
}
else {
temp++;
}
}
}
cin >> operation;
}
return 0;
}
四.KMP算法及其优化
void getNext(string &T,int *next)
{
int i = 0, j = -1;
next[0] = -1;
while (i < T.size() -1)
{
if (j == -1|| T[i] == T[j])
{
i++;
j++;
if (T[i] != T[j])
next[i] = j;
else
next[i] = next[j];
}
else
j = next[j];
}
}
int KMP_method(string &S, string &T)
{
int *next = new int[T.size()];
getNext(T, next);
int i = 0, j = 0;
while (i < S.size() && j < T.size())
{
if (S[i] == T[j])
{
i++;
j++;
}
else if (next[j] == -1)
i++;
else
j = next[j];
}
if (next)
{
delete[]next;
next = NULL;
}
return (j == T.size()) ? i -j : -1;
}
可重叠子串 (Ver. I)
#include <string.h>
#include <iostream>
using namespace std;
void getNext(string& T, int* next)
{
int i = 0, j = -1;
next[0] = -1;
while (i < T.size() - 1)
{
if (j == -1 || T[i] == T[j])
{
i++;
j++;
if (T[i] != T[j])
next[i] = j;
else
next[i] = next[j];
}
else
j = next[j];
}
}
int KMP_method(string& S, string& T)
{
int cnt = 0;
int* next = new int[T.size()];
getNext(T, next);
int i = 0, j = 0;
while (i < S.size())
{
if (j==-1||S[i] == T[j])
{
if (j == (T.size() - 1)) {
i = i - j + 1;
j = 0;
cnt++;
}
else {
i++;
j++;
}
}
else if (next[j] == -1) {
i++;
j = 0;
}
else
j = next[j];
}
if (next)
{
delete[]next;
next = NULL;
}
return cnt;
}
int main()
{
string str;
string ms;
int t;
while (cin >> str)
{
cin >> t;
while (t--)
{
cin >> ms;
int res = KMP_method(str, ms);
cout << ms << ":" << res << endl;
}
}
return 0;
}
五.树
1.二叉树之数组存储
#include<iostream>
using namespace std;
class Tree {
private:
int size;
int* tree;
void preOrder(int i)
{
if (tree[i] != 0 && i < size) {
cout << tree[i] << " ";
preOrder(2 * i + 1);
preOrder(2 * i + 2);
}
}
public:
Tree() {
cin >> size;
tree = new int[size];
for (int i = 0; i < size; i++)
{
cin >> tree[i];
}
}
~Tree() {
delete[] tree;
}
void preOrder() {
preOrder(0);
cout << endl;
}
};
int main()
{
int t;
cin >> t;
while (t--)
{
Tree t1;
t1.preOrder();
}
return 0;
}
2.二叉树之链式存储
#include<iostream>
#include<string>
#include<queue>
#include<stack>
using namespace std;
class BiTreeNode
{
public:
char data;
BiTreeNode* leftChild;
BiTreeNode* rightChild;
BiTreeNode() :leftChild(NULL), rightChild(NULL) {}
};
class BiTree {
private:
int pos;
string strTree;
BiTreeNode* CreateBiTree();
void preOrder(BiTreeNode* t, int temp);
void midOrder(BiTreeNode* t);
void finOrder(BiTreeNode* t);
void levOrder(BiTreeNode* t);
public:
BiTreeNode* Root;
BiTree();
void CreateTree(string TreeArray);
void preOrder();
void midOrder();
void finOrder();
void levOrder();
void invertTree(BiTreeNode* Root);
};
BiTree::BiTree()
{
pos = 0;
strTree = "";
}
void BiTree::CreateTree(string TreeArray)
{
pos = 0;
strTree.assign(TreeArray);
Root = CreateBiTree();
}
void BiTree::invertTree(BiTreeNode* Root) {
if (Root == NULL) return ;
BiTreeNode* temp;
temp = Root->rightChild;
Root->rightChild = Root->leftChild;
Root->leftChild = temp;
invertTree(Root->leftChild);
invertTree(Root->rightChild);
return ;
}
BiTreeNode* BiTree::CreateBiTree()
{
BiTreeNode* T;
char c;
c = strTree[pos++];
if (c == '#')
T = NULL;
else
{
T = new BiTreeNode();
T->data = c;
T->leftChild = CreateBiTree();
T->rightChild = CreateBiTree();
}
return T;
}
void BiTree::preOrder()
{
preOrder(Root, 0);
cout << endl;
}
void BiTree::preOrder(BiTreeNode* t, int temp)
{
if (t != NULL)
{
cout << t->data << " ";
temp++;
preOrder(t->leftChild,temp);
temp++;
preOrder(t->rightChild, temp);
temp++;
}
}
void BiTree::midOrder()
{
midOrder(Root);
cout << endl;
}
void BiTree::midOrder(BiTreeNode* t)
{
if (t != NULL)
{
midOrder(t->leftChild);
cout << t->data << " ";
midOrder(t->rightChild);
}
}
void BiTree::finOrder()
{
finOrder(Root);
cout << endl;
}
void BiTree::finOrder(BiTreeNode* t)
{
if (t != NULL)
{
finOrder(t->leftChild);
finOrder(t->rightChild);
cout << t->data << " ";
}
}
void BiTree::levOrder()
{
levOrder(Root);
cout << endl;
}
void BiTree::levOrder(BiTreeNode* t)
{
queue<BiTreeNode*> tq;
BiTreeNode* p = t;
if (p != NULL)
{
tq.push(p);
}
while (!tq.empty())
{
p = tq.front();
tq.pop();
if (p != NULL)
{
cout << p->data << ' ';
tq.push(p->leftChild);
tq.push(p->rightChild);
}
}
}
int main() {
int t;
cin >> t;
while (t--)
{
string arry;
cin >> arry;
BiTree t1;
t1.CreateTree(arry);
if (t1.Root == NULL) {
cout << "NULL" << endl;
cout << "NULL" << endl;
cout << "NULL" << endl;
cout << "NULL" << endl;
}
t1.invertTree(t1.Root);
t1.preOrder();
t1.midOrder();
t1.finOrder();
t1.levOrder();
}
}
3.二叉树之父子结点
#include<iostream>
#include<string>
#include<queue>
#include<stack>
using namespace std;
class BiTreeNode
{
public:
char data;
BiTreeNode* leftChild;
BiTreeNode* rightChild;
BiTreeNode() :leftChild(NULL), rightChild(NULL) {}
};
class BiTree {
private:
BiTreeNode* Root;
int pos;
string strTree;
BiTreeNode* CreateBiTree();
void PreOrder(BiTreeNode* t);
void PreOrderDad(BiTreeNode* t, BiTreeNode* t2);
public:
BiTree();
void CreateTree(string TreeArray);
void PreOrder();
};
BiTree::BiTree()
{
pos = 0;
strTree = "";
}
void BiTree::CreateTree(string TreeArray)
{
pos = 0;
strTree.assign(TreeArray);
Root = CreateBiTree();
}
BiTreeNode* BiTree::CreateBiTree()
{
BiTreeNode* T;
char c;
c = strTree[pos++];
if (c == '0')
T = NULL;
else
{
T = new BiTreeNode();
T->data = c;
T->leftChild = CreateBiTree();
T->rightChild = CreateBiTree();
}
return T;
}
void BiTree::PreOrder()
{
PreOrder(Root);
cout << endl;
PreOrderDad(Root, Root);
cout << endl;
}
void BiTree::PreOrder(BiTreeNode* t)
{
if (t != NULL)
{
if (t->leftChild == NULL && t->rightChild == NULL)
{
cout << t->data << " ";
}
PreOrder(t->leftChild);
PreOrder(t->rightChild);
}
}
void BiTree::PreOrderDad(BiTreeNode* t, BiTreeNode* t2)
{
if (t != NULL)
{
if (t->leftChild == NULL && t->rightChild == NULL)
{
cout << t2->data << " " ;
}
PreOrderDad(t->leftChild, t);
PreOrderDad(t->rightChild, t);
}
}
int main() {
int t;
cin >> t;
while (t--)
{
string arry;
cin >> arry;
BiTree t1;
t1.CreateTree(arry);
t1.PreOrder();
}
}
六.哈希表
1.链地址法(表头插入,表尾插入)
#include <iostream>
using namespace std;
class hashNode {
public:
int data;
int order;
hashNode* next;
hashNode()
{
data = -1;
order = 1;
next = NULL;
}
};
class hashMap {
private:
hashNode* t;
int key;
public:
hashMap(int n, int key1) {
key = key1;
int d, keyTemp;
t = new hashNode[key];
while (n--) {
cin >> d;
keyTemp = d % key;
if (t[keyTemp].data != -1) {
hashInsert1(&t[keyTemp], d);
}
else
t[keyTemp].data = d;
}
}
int findOrder(hashNode* node, int data)
{
if (node != NULL)
{
if (node->data != data)
return findOrder(node->next, data);
else
return node->order;
}
else
return 0;
}
void hashSearch(int data) {
int keyTemp = data % key;
if (t[keyTemp].data != data)
{
if (findOrder(t[keyTemp].next, data) != 0)
cout << keyTemp << " " << findOrder(t[keyTemp].next, data) << endl;
else
{
hashInsert1(&t[keyTemp], data);
cout << "error" << endl;
}
}
else {
cout << keyTemp << " " << t[keyTemp].order << endl;
}
}
void hashInsert1(hashNode* node, int data) {
if (node->data == -1)
node->data = data;
else {
if (node->next != NULL) {
hashInsert1(node->next, data);
node->order++;
}
else {
hashNode* p = new hashNode();
p->data = data;
node->next = p;
node->order++;
}
}
}
void hashInsert2(hashNode* node, int data) {
if (node->data == -1)
node->data = data;
else {
if (node->next != NULL) {
hashInsert1(node->next, data);
node->order++;
}
else {
hashNode* p = new hashNode();
p->data = data;
p->order = node->order + 1;
node->next = p;
}
}
}
};
int main()
{
int n;
int key = 11;
while (cin >> n) {
hashMap test(n, key);
int t;
cin >> t;
int data;
while (t--)
{
cin >> data;
test.hashSearch(data);
}
}
return 0;
}
2.线性探测再散列
#include <iostream>
using namespace std;
class hashMap {
private:
int* map;
int key;
int len;
public:
hashMap(int m,int n, int key1) {
len = m;
key = key1;
int d, keyTemp;
map = new int[m];
for (int i = 0; i < m; i++)
{
map[i] = -1;
}
while (n--) {
cin >> d;
keyTemp = d % key;
if (map[keyTemp]== -1) {
map[keyTemp] = d;
}
else {
while (1)
{
++keyTemp;
if (keyTemp >= len)
keyTemp = 0;
if (map[keyTemp] == -1) {
map[keyTemp] = d;
break;
}
}
}
}
for (int i = 0; i < m-1; i++)
{
if (map[i] == -1)
cout << "NULL ";
else
cout << map[i] << " ";
}
if (map[m-1] == -1)
cout << "NULL"<<endl;
else
cout << map[m - 1] <<endl;
}
void hashSearch(int data) {
int keyTemp = data % key;
int cnt=0;
for (int i = 0; i < len; i++)
{
cnt++;
if (map[keyTemp] == data) {
cout << "1 " << cnt << " " << keyTemp+1 << endl;
break;
}
else if (map[keyTemp] == -1) {
cout << "0 " << cnt << endl;
break;
}
++keyTemp;
if (keyTemp >= len)
keyTemp = 0;
}
}
};
int main()
{
int t,m,n,data,k;
int key = 11;
cin >> t;
while (t--)
{
cin >> m >> n;
hashMap test(m,n,key);
cin >> k;
while (k--)
{
cin >> data;
test.hashSearch(data);
}
}
return 0;
}
3.Trie树
#include<iostream>
#include<string>
#include<queue>
using namespace std;
class TrieTreeNode
{
public:
string word;
int num;
bool isEnd;
TrieTreeNode** Nextword = new TrieTreeNode * [26];
TrieTreeNode()
{
num = 0;
isEnd = false;
for (int i = 0; i < 26; i++)
{
Nextword[i] = NULL;
}
}
};
class TrieTree
{
private:
TrieTreeNode* Root;
public:
TrieTree();
void insert(string str);
int find(string str);
void show();
};
TrieTree::TrieTree()
{
Root = new TrieTreeNode();
}
void TrieTree::insert(string str)
{
if (str == "" || str.length() == 0)
{
return;
}
TrieTreeNode* T = Root;
int len = str.length();
for (int i = 0; i < len; i++)
{
int pos = str[i] - 'a';
if (T->Nextword[pos] == NULL)
{
T->Nextword[pos] = new TrieTreeNode();
T->Nextword[pos]->word = str[i];
T->Nextword[pos]->num++;
}
else
{
T->Nextword[pos]->num++;
}
T = T->Nextword[pos];
}
T->isEnd = true;
}
int TrieTree::find(string str)
{
if (str == "" || str.length() == 0)
{
return 0;
}
TrieTreeNode* T = Root;
int len = str.length();
for (int i = 0; i < len; i++)
{
int pos = str[i] - 'a';
if (T->Nextword[pos] != NULL)
{
T = T->Nextword[pos];
}
else
{
return 0;
}
}
return T->num;
}
void TrieTree::show()
{
if (!Root) return;
deque<TrieTreeNode*> q;
q.push_back(Root);
while (!q.empty())
{
int qs = q.size();
for (int i = 0; i < qs; i++)
{
TrieTreeNode* tp = q.front(); q.pop_front();
cout << tp->word;
for (int i = 0; i < 26; i++)
if (tp->Nextword[i]) q.push_back(tp->Nextword[i]);
}
}
cout << endl;
}
int main() {
string str;
int t;
TrieTree tree;
while (1)
{
cin>>str;
if (str[0] <= '9' && str[0] >= '0') {
t = str[0] - '0';
break;
}
tree.insert(str);
}
tree.show();
while (t--)
{
cin >> str;
int res=tree.find(str);
cout << res << endl;
}
}
4.二次探测再散列
#include <iostream>
using namespace std;
class hashMap {
private:
int* map;
int key;
int len;
public:
hashMap(int m, int n, int key1) {
len = m;
key = key1;
int d, keyTemp;
map = new int[m];
for (int i = 0; i < m; i++)
{
map[i] = -1;
}
while (n--) {
cin >> d;
keyTemp = d % key;
if (map[keyTemp] == -1|| map[keyTemp] == d) {
map[keyTemp] = d;
}
else {
int num = 0;
while (1)
{
num += 1;
int temp = keyTemp + num * num;
while (temp < 0 || temp> (m - 1) ) {
if (temp < 0)
temp += m;
else if (temp > (m - 1))
temp -= m;
}
if (map[temp] == -1 || map[temp] == d) {
map[temp] = d;
break;
}
temp = keyTemp - num * num;
while (temp < 0 || temp>(m - 1)) {
if (temp < 0)
temp += m;
else if (temp > (m - 1))
temp -= m;
}
if (map[temp] == -1 || map[temp] == d) {
map[temp] = d;
break;
}
}
}
}
for (int i = 0; i < m - 1; i++)
{
if (map[i] == -1)
cout << "NULL ";
else
cout << map[i] << " ";
}
if (map[m-1] == -1)
cout << "NULL" << endl;
else
cout << map[m - 1] <<endl;
}
void hashSearch(int data) {
int keyTemp = data % key;
int cnt = 0;
int temp = keyTemp;
int num = 0;
cnt++;
if (map[temp] == data) {
cout << "1 " << cnt << " " << temp + 1 << endl;
return;
}
else if (map[temp] == -1) {
cout << "0 " << cnt << endl;
return;
}
while (1)
{
cnt++;
num += 1;
temp = keyTemp + num * num;
while (temp < 0 || temp>(len - 1)) {
if (temp < 0)
temp += len;
else if (temp > (len - 1))
temp -= len;
}
if (map[temp] == data) {
cout << "1 " << cnt << " " << temp + 1 << endl;
break;
}
else if (map[temp] == -1) {
cout << "0 " << cnt << endl;
break;
}
cnt ++;
temp = keyTemp - num * num;
while (temp < 0 || temp>(len - 1)) {
if (temp < 0)
temp += len;
else if (temp > (len - 1))
temp -= len;
}
if (map[temp] == data) {
cout << "1 " << cnt << " " << temp + 1 << endl;
break;
}
else if (map[temp] == -1) {
cout << "0 " << cnt << endl;
break;
}
}
}
};
int main()
{
int t, m, n, data, k;
int key = 11;
cin >> t;
while (t--)
{
cin >> m >> n;
hashMap test(m, n, key);
cin >> k;
while (k--)
{
cin >> data;
test.hashSearch(data);
}
}
return 0;
}
七.排序
1.直插排序
#include<iostream>
using namespace std;
void straightSort(int* arr, int len)
{
int tmp;
int i;
int j;
for (i = 1; i < len; i++)
{
tmp = arr[i];
for (j = i - 1; j >= 0 && arr[j] > tmp; j--)
{
arr[j + 1] = arr[j];
}
arr[j + 1] = tmp;
for (int i = 0; i < len-1; i++)
{
cout << arr[i] << " ";
}
cout << arr[len - 1];
cout << endl;
}
}
int main()
{
int n;
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
straightSort(arr, n);
return 0;
}
2.希尔排序
#include<iostream>
using namespace std;
void shellSort(int* item, int n)
{
int gap = n / 2;
while (gap >= 1)
{
int t = gap;
int pos = 0;
while (t--)
{
for (int i = pos; i < n; i += gap)
{
for (int k = pos; k < n - gap; k += gap)
{
if (item[k] <= item[k + gap])
{
int m = item[k];
item[k] = item[k + gap];
item[k + gap] = m;
}
}
}
pos++;
}
for (int i = 0; i < n; i++)
{
cout << item[i] << " ";
}
if(gap!=1)
cout << endl;
gap = gap / 2;
}
}
int main()
{
int t,n;
cin >> t;
while (t--) {
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
shellSort(arr, n);
if(t!=0)
cout<<endl<<endl;
}
return 0;
}
3.冒泡排序
#include<iostream>
using namespace std;
void bubbleSort(int* item, int len)
{
int res = 0;
for (int k = 0; k < len - 1; k++)
{
for (int j = 0; j < len - (k + 1); j++)
{
if (item[j] > item[j + 1])
{
int temp = item[j];
item[j] = item[j + 1];
item[j + 1] = temp;
res++;
}
}
}
cout << res << endl;
}
int main()
{
int n;
while (cin >> n)
{
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
bubbleSort(arr, n);
}
return 0;
}
4.快速排序
#include<iostream>
#include<string>
#include<queue>
#include<stack>
using namespace std;
void quickSort(int* arr, int start, int end,int n) {
if (start < end)
{
int i = start, j = end, x = arr[start];
while (i < j)
{
while (i < j && arr[j] >= x)
j--;
if (i < j)
arr[i++] = arr[j];
while (i < j && arr[i] < x)
i++;
if (i < j)
arr[j--] = arr[i];
}
arr[i] = x;
for (int i = 0; i <n; i++)
{
if (i != 0)
cout << " ";
cout << arr[i];
}
cout << endl;
quickSort(arr, start, i - 1, n);
quickSort(arr, i + 1, end, n);
}
}
int main() {
int t,n;
cin >> t;
while (t--)
{
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
quickSort(arr, 0, n-1,n);
cout << endl;
}
}
5.堆排序
#include<iostream>
using namespace std;
class HeapSort
{
private:
int* item;
int len;
public:
HeapSort(int n)
{
len = n;
item = new int[len];
for (int i = 0; i < len; i++)
{
cin >> item[i];
}
}
void sort()
{
for (int i = len / 2 - 1; i >= 0; i--)
{
adjustHeap(i, len);
}
display();
for (int j = len - 1; j > 0; j--)
{
swap(0, j);
adjustHeap(0, j);
display();
}
}
void adjustHeap(int i, int length)
{
int temp = item[i];
for (int k = i * 2 + 1; k < length; k = k * 2 + 1)
{
if (k + 1 < length && item[k] > item[k + 1])
{
k++;
}
if (item[k] < temp)
{
item[i] = item[k];
i = k;
}
}
item[i] = temp;
}
void swap(int a, int b)
{
int m = item[a];
item[a] = item[b];
item[b] = m;
}
void display()
{
cout << len << " ";
for (int i = 0; i < len-1; i++)
{
cout << item[i] << " ";
}
cout << item[len - 1];
cout << endl;
}
};
int main() {
int n;
cin >> n;
HeapSort test(n);
test.sort();
}
6.折半插入排序
#include<iostream>
using namespace std;
void binaryInsertSort(int* item, int n)
{
int temp;
for (int i = 1; i < n; i++)
{
temp = item[i];
int low = 0;
int high = i - 1;
int mid;
while (low <= high)
{
mid = (low + high) / 2;
if (temp > item[mid])
high = mid - 1;
else
low = mid + 1;
}
int j;
for (j = i - 1; j >= high + 1; j--)
item[j + 1] = item[j];
item[j + 1] = temp;
for (int k = 0; k < n-1; k++)
{
cout << item[k] << " ";
}
cout << item[n - 1];
cout << endl;
}
}
int main() {
int n,t;
cin >> t;
while (t--) {
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
binaryInsertSort(arr, n);
cout << endl;
}
}
7.简单选择排序
#include<iostream>
using namespace std;
void selectSort(int* item, int n)
{
int min;
for (int i = 0; i < n; i++)
{
min = i;
for (int k = i + 1; k < n; k++)
{
if (item[k] < item[min])
{
min = k;
}
}
int m = item[i];
item[i] = item[min];
item[min] = m;
for (int i = 0; i < n-1; i++)
{
cout << item[i] << " ";
}
cout << item[n - 1];
cout << endl;
}
}
int main() {
int n,t;
cin >> t;
while (t--) {
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
selectSort(arr, n);
cout << endl;
}
}
8.二路归并排序
#include<iostream>
#include<string.h>
using namespace std;
string* commonSort(int n, string* strAry) {
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
if (strAry[i] < strAry[j]) {
string temp = strAry[j];
strAry[j] = strAry[i];
strAry[i] = temp;
}
}
}
return strAry;
}
void outPut(int n, string* strAry) {
for (int i = 0; i < n - 1; i++)
{
cout << strAry[i] << " ";
}
cout << strAry[n - 1] << endl;
}
void twoMergeSort(string* strAry,int len) {
int flag = 0;
int n = 2;
int num = 0;
while ((n/2) <= len)
{
for (int i = 0; i <= len / n; i++)
{
string* temp = new string[n];
for (int j = 0; j < n; j++)
{
if (len > (j + i * n)) {
temp[j] = strAry[j + i * n];
num++;
}
}
int len2 = num;
num = 0;
temp = commonSort(len2, temp);
for (int k = 0; k < len2; k++)
{
strAry[k + i * n] = temp[k];
}
delete[]temp;
}
n *= 2;
outPut(len, strAry);
}
}
int main() {
int n, t;
cin >> t;
while (t--) {
cin >> n;
string* strArray = new string[n];
for (int i = 0; i < n; i++)
{
cin >> strArray[i];
}
twoMergeSort(strArray,n);
cout << endl;
}
}
9.基数排序
#include <iostream>
#include <vector>
using namespace std;
void radixSort()
{
int n;
cin >> n;
int* nums = new int[n];
int t = 9;
for (int i = 0; i < n; i++)
{
cin >> nums[i];
while (nums[i] > t)
t = t * 10 + 9;
}
vector<vector<int> > number;
for (int i = 0; i < 10; i++)
{
vector<int> temp;
number.push_back(temp);
}
int te = 10;
while (te < 10 * t)
{
for (int i = 0; i < n; i++)
{
int k = nums[i];
k = k % te;
k = k / (te / 10);
number[k].push_back(nums[i]);
}
int p = 0;
for (int i = 0; i < 10; i++)
{
cout << i << ':';
if (number[i].empty())
cout << "NULL" << endl;
else
{
for (int j = 0; j < number[i].size(); j++)
{
cout << "->" << number[i][j];
nums[p++] = number[i][j];
}
cout << "->^" << endl;
number[i].clear();
}
}
for (int i = 0; i < n; i++)
{
cout << nums[i];
if (i != n - 1)
cout << ' ';
}
cout << endl;
te *= 10;
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
radixSort();
cout << endl;
}
}
总结
|