数据结构模板
链表
单链表
/*************************************************
**************************************************/
#include<iostream> //引入输入输出流
using namespace std;
template <typename DataType>
struct Node
{
DataType data; //数据域
Node *next; //指针域
};
template <typename DataType>
class LinkList
{
public:
LinkList( ); //无参构造函数,建立只有头结点的空链表
LinkList(DataType a[ ], int n); //有参构造函数,建立有n个元素的单链表
~LinkList( ); //析构函数
int Length( ); //求单链表的长度
int Empety();
DataType Get(int i); //按位查找。查找第i个结点的元素值
int Locate(DataType x); //按值查找。查找值为x的元素序号
void Insert(int i, DataType x); //插入操作,第i个位置插入值为x的结点
DataType Delete(int i); //删除操作,删除第i个结点
void PrintList( ); //遍历操作,按序号依次输出各元素
private:
Node<DataType> *first; //单链表的头指针
};
template <typename DataType>
LinkList<DataType> :: LinkList( )
{
first = new Node<DataType>; //生成头结点
first->next = nullptr; //头结点的指针域置空
}
template <typename DataType>
LinkList<DataType> :: ~LinkList( )
{
Node<DataType> *q = NULL;
while (first != NULL) //释放单链表的每一个结点的存储空间
{
q = first; //暂存被释放结点
first = first->next; // first指向被释放结点的下一个结点
delete q;
}
}
template <typename DataType>
int LinkList<DataType> :: Empety()
{
if(first->next == nullptr)
return 1;
else
return 0;
}
template <typename DataType>
void LinkList<DataType> :: PrintList( )
{
Node<DataType> *p = first->next; //工作指针p初始化
while (p != nullptr)
{
cout << p->data << " ";
p = p->next; //工作指针p后移,注意不能写作p++
}
}
template <typename DataType>
int LinkList<DataType> :: Length( )
{
Node<DataType> *p = first->next; //工作指针p初始化为开始接点
int count = 0; //累加器count初始化
while (p != nullptr)
{
p = p->next;
count++;
}
return count; //注意count的初始化和返回值之间的关系
}
template <typename DataType>
DataType LinkList<DataType> :: Get(int i)
{
Node<DataType> *p = first->next; //工作指针p初始化
int count = 1; //累加器count初始化
while (p != nullptr && count < i)
{
p = p->next; //工作指针p后移
count++;
}
if (p == nullptr) throw "位置";
else return p->data;
}
template <typename DataType>
int LinkList<DataType> :: Locate(DataType x)
{
Node<DataType> *p = first->next; //工作指针p初始化
int count = 1; //累加器count初始化
while (p != nullptr)
{
if (p->data == x) return count; //查找成功,结束函数并返回序号
p = p->next;
count++;
}
return 0; //退出循环表明查找失败
}
template <typename DataType>
void LinkList<DataType> :: Insert(int i, DataType x)
{
Node<DataType> *p = first, *s = nullptr ; //工作指针p初始化
int count = 0;
while (p != nullptr && count < i - 1) //查找第i – 1个结点
{
p = p->next; //工作指针p后移
count++;
}
if (p == nullptr) throw "位置"; //没有找到第i – 1个结点
else
{
s = new Node<DataType>;
s->data = x; //申请结点s,数据域为x
s->next = p->next;
p->next = s; //将结点s插入到结点p之后
}
}
// 头插法构造
//template
//LinkList :: LinkList(DataType a[ ], int n)
//{
// first = new Node; first->next = nullptr; //初始化一个空链表
// for (int i = 0; i < n; i++)
// {
// Node *s;
// s = new Node; s->data = a[i];
// s->next = first->next; first->next = s; //将结点s插入到头结点之后
// }
//}
template <typename DataType>
LinkList<DataType> :: LinkList(DataType a[ ], int n)
{
first = new Node<DataType>; //生成头结点
Node<DataType> *r = first, *s = nullptr; //尾指针初始化
for (int i = 0; i < n; i++)
{
s = new Node<DataType>;
s->data = a[i];
r->next = s;
r = s; //将结点s插入到终端结点之后
}
r->next = nullptr; //单链表建立完毕,将终端结点的指针域置空
}
template <typename DataType>
DataType LinkList<DataType> :: Delete(int i)
{
DataType x;
Node<DataType> *p = first, *q = nullptr; //工作指针p指向头结点
int count = 0;
while (p != nullptr && count < i - 1) //查找第i-1个结点
{
p = p->next;
count++;
}
if (p == nullptr || p->next == nullptr) //结点p不存在或p的后继结点不存在
throw "位置";
else
{
q = p->next;
x = q->data; //暂存被删结点
p->next = q->next; //摘链
delete q;
return x;
}
}
int main( )
{
int r[5] = {1, 2, 3, 4, 5}, i, x;
LinkList<int> L{r, 5};
cout << "当前线性表的数据为:";
L.PrintList( ); //输出当前链表1 2 3 4 5
cout << endl;
try
{
L.Insert(2, 8); //在第2个位置插入值为8的结点
cout << "执行插入操作后数据为:";
L.PrintList( ); //输出插入后链表1 8 2 3 4 5
cout << endl;
}
catch(char* str)
{
cout << str << endl;
}
cout << "当前单链表的长度为:" << L.Length( ) << endl; //输出单链表长度6
cout << "请输入查找的元素值:";
cin >> x;
i = L.Locate(x);
if (1 <= i) cout << "元素" << x << "的元素位置为:" << i << endl;
else cout << "单链表中没有元素" << x << endl;
try
{
cout << "请输入要删除第几个元素:";
cin >> i;
x = L.Delete(i); //删除第i个元素
cout << "删除的元素值是" << x << "执行删除操作后数据为:";
L.PrintList( ); //输出删除后链表
}
catch(char* str)
{
cout << str << endl;
}
return 0;
}
双链表
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
template <typename one>
struct Node
{
one data;
Node* piot;
Node* next;
};
template <typename one>
class Double_linked_list
{
public:
Double_linked_list(one a[],int n);
Double_linked_list();
~Double_linked_list();
int Length( );
int Empety();
one Get(int i);
int Locate(one x); //按值查找。查找值为x的元素序号
void Insert(int i, one x); //插入操作,第i个位置插入值为x的结点
one Delete(int i); //删除操作,删除第i个结点
void PrintList( ); //遍历操作,按序号依次输出各元素
private:
Node<one> *first,*tail; //单链表的头指针
};
template <typename one>
Double_linked_list<one> :: Double_linked_list( )
{
first = new Node<one>; //生成头结点
first->next = nullptr; //头结点的指针域置空
}
template <typename one>
Double_linked_list<one> :: ~Double_linked_list( )
{
Node<one> *q = NULL;
while (first != NULL) //释放单链表的每一个结点的存储空间
{
q = first; //暂存被释放结点
first = first->next; // first指向被释放结点的下一个结点
delete q;
}
}
template <typename one>
int Double_linked_list<one> :: Empety()
{
if(first->next == nullptr)
return 1;
else
return 0;
}
template <typename one>
void Double_linked_list<one> :: PrintList( )
{
Node<one> *p = first->next; //工作指针p初始化
while (p != nullptr)
{
cout << p->data << " ";
p = p->next; //工作指针p后移,注意不能写作p++
}
}
template <typename one>
int Double_linked_list<one> :: Length( )
{
Node<one> *p = first->next; //工作指针p初始化为开始接点
int count = 0; //累加器count初始化
while (p != nullptr)
{
p = p->next;
count++;
}
return count; //注意count的初始化和返回值之间的关系
}
template <typename one>
one Double_linked_list<one> :: Get(int i)
{
Node<one> *p = first->next; //工作指针p初始化
int count = 1; //累加器count初始化
while (p != nullptr && count < i)
{
p = p->next; //工作指针p后移
count++;
}
if (p == nullptr)
throw "位置";
else
return p->data;
}
template <typename one>
int Double_linked_list<one> :: Locate(one x)
{
Node<one> *p = first->next; //工作指针p初始化
int count = 1; //累加器count初始化
while (p != nullptr)
{
if (p->data == x)
return count; //查找成功,结束函数并返回序号
p = p->next;
count++;
}
return 0; //退出循环表明查找失败
}
template <typename one>
void Double_linked_list<one> :: Insert(int i, one x)
{
Node<one> *p = first, *s = nullptr ; //工作指针p初始化
int count = 0;
while (p != nullptr && count < i - 1) //查找第i – 1个结点
{
p = p->next; //工作指针p后移
count++;
}
if (p == nullptr)
throw "位置"; //没有找到第i – 1个结点
else
{
s = new Node<one>;
s->data = x; //申请结点s,数据域为x
s->next = p->next;
s->piot = p;
p->next->piot = s;
p->next = s; //将结点s插入到结点p之后
}
}
// 头插法构造
//template
//Double_linked_list :: Double_linked_list(one a[ ], int n)
//{
// first = new Node; first->next = nullptr; //初始化一个空链表
// for (int i = 0; i < n; i++)
// {
// Node *s;
// s = new Node; s->data = a[i];
// s->next = first->next; first->next = s; //将结点s插入到头结点之后
// }
//}
template <typename one>
Double_linked_list<one> :: Double_linked_list(one a[ ], int n)
{
first = new Node<one>; //生成头结点
tail = new Node<one>;
tail->piot = nullptr;
Node<one> *r = first, *s = nullptr; //尾指针初始化
for (int i = 0; i < n; i++)
{
s = new Node<one>;
s->data = a[i];
s->piot = tail->piot;
tail->piot = s;
r->next = s;
r = s; //将结点s插入到终端结点之后
}
r->next = nullptr; //单链表建立完毕,将终端结点的指针域置空
}
template <typename one>
one Double_linked_list<one> :: Delete(int i)
{
one x;
Node<one> *p = first, *q = nullptr; //工作指针p指向头结点
int count = 0;
while (p != nullptr && count < i - 1) //查找第i-1个结点
{
p = p->next;
count++;
}
if (p == nullptr || p->next == nullptr) //结点p不存在或p的后继结点不存在
throw "位置";
else
{
q = p->next;
x = q->data; //暂存被删结点
p->next = q->next; //摘链
q->next->piot = p;
delete q;
return x;
}
}
int main( )
{
int r[5] = {1, 2, 3, 4, 5}, i, x;
Double_linked_list<int> L{r, 5};
cout << "当前线性表的数据为:";
L.PrintList( ); //输出当前链表1 2 3 4 5
cout << endl;
try
{
L.Insert(2, 8); //在第2个位置插入值为8的结点
cout << "执行插入操作后数据为:";
L.PrintList( ); //输出插入后链表1 8 2 3 4 5
cout << endl;
}
catch(char* str)
{
cout << str << endl;
}
cout << "当前单链表的长度为:" << L.Length( ) << endl; //输出单链表长度6
cout << "请输入查找的元素值:";
cin >> x;
i = L.Locate(x);
if (1 <= i)
cout << "元素" << x << "的元素位置为:" << i << endl;
else
cout << "单链表中没有元素" << x << endl;
try
{
cout << "请输入要删除第几个元素:";
cin >> i;
x = L.Delete(i); //删除第i个元素
cout << "删除的元素值是" << x << "执行删除操作后数据为:";
L.PrintList( ); //输出删除后链表
}
catch(char* str)
{
cout << str << endl;
}
return 0;
}
顺序表
#include<bits/stdc++.h>
using namespace std;
const int MaxSize = 100; //100只是示例性的数据,根据实际问题具体定义
template <typename DataType>
class SeqList
{
public:
SeqList( ); //无参构造函数,建立空的顺序表
SeqList(DataType a[ ], int n); //有参构造函数,建立长度为n的顺序表
~SeqList( ); //析构函数
int Length( ); //求线性表的长度
int Empety();
DataType Get(int i); //按位查找,查找第i个元素的值
int Locate(DataType x ); //按值查找,查找值为x的元素序号
void Insert(int i, DataType x); //插入操作,在第i个位置插入值为x的元素
DataType Delete(int i); //删除操作,删除第i个元素
void PrintList( ); //遍历操作,按序号依次输出各元素
private:
DataType data[MaxSize]; //存放数据元素的数组
int length; //线性表的长度
};
template <typename DataType>
SeqList<DataType>:: ~SeqList()
{
}
template <typename DataType>
SeqList<DataType>:: SeqList()
{
length = 0;
}
template <typename DataType>
int SeqList<DataType>:: Empety()
{
if(length == 0)
return 1;
else
return 0;
}
template < typename DataType >
int SeqList<DataType>:: Length()
{
return length;
}
template <typename DataType>
SeqList<DataType>::SeqList(DataType a[ ], int n)
{
if (n > MaxSize)
throw "参数非法";
for (int i = 0; i < n; i++)
data[i] = a[i];
length = n;
}
template <typename DataType>
void SeqList<DataType>:: PrintList( )
{
for (int i = 0; i < length; i++)
cout << data[i]; //依次输出线性表的元素值
}
template <typename DataType>
int SeqList<DataType>::Locate(DataType x)
{
for (int i = 0; i < length; i++)
if (data[i] == x)
return i+1; //返回其序号i+1
return 0; //退出循环,说明查找失败
}
template <typename DataType>
DataType SeqList<DataType>:: Get(int i)
{
if (i < 1 && i > length)
throw "查找位置非法";
else
return data[i - 1];
}
template <typename DataType>
DataType SeqList<DataType>:: Delete(int i)
{
if (length == 0)
throw "下溢";
if (i < 1 || i > length)
throw "位置";
int x = data[i - 1]; //取出位置i的元素
for (int j = i; j < length; j++)
data[j - 1] = data[j]; //此处j已经是元素所在的数组下标
length--;
return x;
}
template <typename DataType>
void SeqList<DataType>::Insert(int i, DataType x)
{
if (length >= MaxSize)
throw "上溢";
if (i < 1 || i > length + 1)
throw "位置";
for (int j = length; j >= i; j--)
data[j] = data[j - 1]; //第j个元素存在数组下标为j-1处
data[i - 1] = x;
length++;
}
int main( )
{
int r[5] = {1, 2, 3, 4, 5}, i, x;
SeqList<int>L{r, 5}; //建立具有5个元素的顺序表
cout << "当前线性表的数据为:";
L.PrintList( ); //输出当前线性表1 2 3 4 5
try
{
L.Insert(2, 8); //在第2个位置插入值为8的元素
cout << endl << "执行插入操作后数据为:";
L.PrintList( ); //输出插入后的线性表1 8 2 3 4 5
cout << endl;
}
catch(char* str)
{
cout << str << "插入操作错误!" << endl;
}
cout << "当前线性表的长度为:" << L.Length( ); //输出线性表的长度6
cout << endl;
cout << "请输入查找的元素值:";
cin >> x;
i = L.Locate(x);
if (0 == i)
cout << "查找失败" << endl;
else
cout << "元素" << x << "的位置为:" << i << endl;
try
{
cout << "请输入查找第几个元素值:";
cin >> i;
cout << "第" << i << "个元素值是" << L.Get(i) << endl;
}
catch(char* str)
{
cout << "线性表中没有该元素" << endl;
}
try
{
cout << "请输入要删除第几个元素:";
cin >> i;
x = L.Delete(i); //删除第i个元素
cout << "删除的元素是" << x <<",删除后数据为:";
L.PrintList( ); //输出删除后的线性表
}
catch(char* str)
{
cout << "删除错误!" << endl;
}
return 0;
}
栈与队列
表达式求值
/*********************************
表达式求值
**********************************/
#include <iostream>
#include <string>
using namespace std;
class Expression
{
public:
Expression(string str); //构造函数
~Expression( ); //析构函数
int Compute( ); //计算表达式str的值
private:
int Comp(char str1, char str2); //比较str1的str2优先级
string str;
};
Expression :: Expression(string str) //接收键盘输入并加上定界符
{
this->str = str + "#";
}
Expression :: ~Expression( )
{
}
int Expression :: Compute( )
{
char OPND[100], OPTR[100]; //定义两个顺序栈
OPTR[0] = '#'; //栈OPTR初始化为定界符
int top1 = -1, top2 = 0; //初始化栈OPND和OPTR的栈顶指针
int i, k, x, y, z, op;
for (i = 0; str[i] != '\0'; ) //依次扫描每一个字符
{
if (str[i] >= 48 && str[i] <= 57) //数字0的ASCII码是48
OPND[++top1] = str[i++] - 48; //将字符转换为数字压栈
else
{
k = Comp(str[i], OPTR[top2]);
if (k == 1) //str[i]的优先级高
OPTR[++top2] = str[i++]; //将str[i]压入运算符栈
else if (k == -1) //str[i]的优先级低
{
y = OPND[top1--]; //从运算对象栈出栈两个元素
x = OPND[top1--];
op = OPTR[top2--]; //从运算符栈出栈一个元素
switch (op) // op为运算符,进行相应运算
{
case '+':
z = x + y;
break;
case '-':
z = x - y;
break;
case '*':
z = x * y;
break;
case '/':
z = x / y;
break;
default:
break;
}
OPND[++top1] = z; //运算结果入运算对象栈
}
else
{
//str[i]与运算符栈的栈顶元素优先级相同
top2--; //匹配str[i],扫描下一个字符
i++;
}
}
}
return OPND[top1]; //运算对象栈的栈顶元素即为运算结果
}
int Expression :: Comp(char str1, char str2)
{
//比较str1和str2的优先级,1:str1高;0:相同;-1:str1低
switch (str1)
{
case '+':
case '-':
if (str2 == '(' || str2 == '#')
return 1;
else
return -1;
break;
case '*':
case '/':
if (str2 == '*' || str2 == '/')
return -1;
else
return 1;
break;
case '(':
return 1;
break;
case ')':
if (str2 == '(')
return 0;
else
return -1;
break;
case '#':
if (str2 == '#')
return 0;
else
return -1;
break;
default:
break;
}
}
int main( )
{
string str;
cout << "请输入一个表达式:" << endl;
cin >> str;
Expression E{str}; //定义对象变量E
int result = E.Compute( ); //result保存计算结果
cout << "表达式的值是:" << result << endl;
return 0;
}
括号匹配问题
/**********************************
括号匹配问题
***********************************/
#include<iostream>
#include<string>
using namespace std;
class Matcher{
public:
Matcher(string str);
~Matcher(){ };
int match();
private:
string str;
};
Matcher :: Matcher(string str){
this->str = str;
}
int Matcher :: match()
{
string S; /*定义一个字符对象 */
int i, top = -1; /* top为字符对象S的尾指针 */
for (i = 0; str[i] != '\0'; i++) /* 依次对str对象的每个字符, str[i]进行处理 */
{
if (str[i] == ')') { /*当前扫描的字符是右括号*/
if (top > -1) top--; /*出栈前判断栈是否为空*/
else return -1;
}
else if (str[i] == '(') /*当前扫描的字符是左括号*/
S[++top] = str[i]; /*执行入栈操作*/
}
if (top == -1) return 0; /*栈空则括号正确匹配*/
else return 1;
}
int main( )
{
string str; /*定义尽可能大的字符数组以接收键盘的输入*/
int k; /*k接收调用函数Match的结果*/
cout << "请输入一个算术表达式:";
cin >> str; /*将表达式以字符串方式输入*/
Matcher m{str};
k = m.match( ); /*函数调用,实参为字符数组的首地址*/
if (k == 0)
cout << "正确匹配\n";
else if (k == 1)
cout << "多左括号\n";
else
cout << "多右括号\n";
return 0;
}
链队列
/************************************************
链队列类LinkQueue的使用范例
*************************************************/
#include<iostream>
using namespace std;
template<typename DataType>
struct Node
{
DataType data; //数据域
Node *next; //指针域
};
template<typename DataType>
class LinkQueue
{
public:
LinkQueue( ); //构造函数,初始化一个空的链队列
~LinkQueue( ); //析构函数,释放链队列各结点的存储空间
void EnQueue(DataType x); //入队操作,将元素x入队
DataType DeQueue( ); //出队操作,将队头元素出队
DataType GetQueue( ); //取链队列的队头元素
int Empty( ); //判断链队列是否为空
private:
Node<DataType> *front, *rear; //队头和队尾指针,分别指向头结点和终端结点
};
template<typename DataType>
LinkQueue<DataType>:: LinkQueue( )
{
Node<DataType> *s = nullptr;
s = new Node<DataType>;
s->next = nullptr; //创建头结点s
front = rear = s; //将队头指针和队尾指针都指向头结点s
}
template<typename DataType>
LinkQueue<DataType>:: ~LinkQueue()
{
Node<DataType>*q = nullptr;
while (front != nullptr) //释放单链表的每一个结点的存储空间
{
q = front; //暂存被释放结点
front = front->next; // front指向被释放结点的下一个结点
delete q;
}
}
template<typename DataType>
void LinkQueue<DataType>:: EnQueue(DataType x)
{
Node<DataType> *s = nullptr;
s = new Node<DataType>; //申请结点s
s->data = x;
s->next = nullptr;
rear->next = s;
rear = s; //将结点s插入到队尾
}
template<typename DataType>
DataType LinkQueue<DataType>:: DeQueue( )
{
DataType x;
Node<DataType>*p = nullptr;
if (rear == front) throw "下溢";
p = front->next;
x = p->data; //暂存队头元素
front->next = p->next; //将队头元素所在结点摘链
if (p->next == nullptr) rear = front; //判断出队前队列长度是否为1
delete p;
return x;
}
template<typename DataType>
DataType LinkQueue<DataType>:: GetQueue()
{
if(front == rear)
throw "下溢异常";
else
return front->next->data;
}
template<typename DataType>
int LinkQueue<DataType>:: Empty()
{
if(front == rear)
return 1;
else
return 0;
}
int main( )
{
int x;
LinkQueue<int>Q{ }; //定义对象变量Q
cout << "对5和8执行入队操作,";
Q.EnQueue(5);
Q.EnQueue(8);
cout << "当前队头元素为:" << Q.GetQueue( ) << endl; //输出队头元素5
try
{
x = Q.DeQueue( );
cout << "执行一次出队操作,出队元素是:" << x << endl; //输出出队元素5
}
catch(char* str)
{
cout << str << endl;
}
try
{
cout << "请输入入队元素:";
cin >> x;
Q.EnQueue(x);
}
catch(char* str)
{
cout << str << endl;
}
if (Q.Empty( ) == 1) cout << "队列为空" << endl;
else cout << "队列非空" << endl; //队列有2个元素,输出队列非空
return 0;
}
链栈
/************************************************
链栈类LinkStack的使用范例
*************************************************/
#include<iostream>
using namespace std;
template<typename DataType>
struct Node
{
DataType data; //数据域
Node *next; //指针域
};
template<typename DataType>
class LinkStack
{
public:
LinkStack( ); //构造函数,初始化一个空链栈
~LinkStack( ); //析构函数,释放链栈各结点的存储空间
void Push(DataType x); //入栈操作,将元素x入栈
DataType Pop( ); //出栈操作,将栈顶元素出栈
DataType GetTop( ); //取栈顶元素(并不删除)
int Empty( ); //判空操作,判断链栈是否为空栈
private:
Node<DataType> *top; //栈顶指针即链栈的头指针
};
template<typename DataType>
LinkStack<DataType> :: LinkStack()
{
top = new Node<DataType>; //生成头结点
top->next = nullptr; //头结点的指针域置空
}
template<typename DataType>
LinkStack<DataType> :: ~LinkStack()
{
Node<DataType> *q = nullptr;
while (top != nullptr) //释放链栈的每一个结点的存储空间
{
q = top; //暂存被释放结点
top = top->next; // top指向被释放结点的下一个结点
delete q;
}
}
template<typename DataType>
DataType LinkStack<DataType> :: GetTop()
{
if(top == nullptr)
throw "下溢异常";
else
return top->data;
}
template<typename DataType>
void LinkStack<DataType> :: Push(DataType x)
{
Node<DataType> *s = nullptr;
s = new Node<DataType>;
s->data = x; //申请结点s数据域为x
s->next = top;
top = s; //将结点s插在栈顶
}
template<typename DataType>
DataType LinkStack<DataType> :: Pop( )
{
Node<DataType> *p = nullptr;
DataType x;
if (top == nullptr) throw "下溢";
x = top->data;
p = top; //暂存栈顶元素
top = top->next; //将栈顶结点摘链
delete p;
return x;
}
template<typename DataType>
int LinkStack<DataType> :: Empty()
{
if(top == nullptr)
throw "下溢异常";
else
return 0;
}
int main( )
{
int x;
LinkStack<int> S{ }; //定义链栈变量S
cout << "对15和10执行入栈操作,";
S.Push(15);
S.Push(10);
cout << "当前栈顶元素为:" << S.GetTop( ) << endl; //输出栈顶元素10
try
{
x = S.Pop( );
cout << "执行一次出栈操作,删除元素:" << x << endl; //输出出栈元素10
}
catch(char* str)
{
cout << str << endl;
}
try
{
cout << "请输入待插入元素:";
cin >> x;
S.Push(x);
}
catch(char* str)
{
cout << str << endl;
}
if (S.Empty( ) == 1) cout << "栈为空" << endl;
else cout << "栈非空" << endl; //栈有2个元素,输出栈非空
return 0;
}
逆波兰式
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 110;
int Ints(char str1, char str2)
{
switch(str1)
{
case'+':case'-':if(str2 == '(' || str2 == '#') return 1;else return -1;break;
case'*':case'/':if(str2 == '*' || str2 == '/') return -1;else return 1;break;
case'(':return 1;break;
case')':if(str2 == '(') return 0;else return -1;break;
case'#':if(str2 == '#') return 0;else return -1;break;
}
}
ll Cals(string str)
{
char Num[N],Oper[N];
int top1 = -1, top2 = 0;
Oper[top2] = '#';
int z;
for(int i = 0; str[i];)
{
if(str[i] >= 48 && str[i] <= 58) Num[++top1] = str[i++] - 48;
else
{
int k = Ints(str[i],Oper[top2]);
if(k == 1) Oper[++top2] = str[i++];
else if(k == -1)
{
int y = Num[top1--];
int x = Num[top1--];
char op = Oper[top2--];
switch(op)
{
case'+': z = x + y;break;
case'-': z = x - y;break;
case'*': z = x * y;break;
case'/': z = x / y;break;
default:break;
}
Num[++top1] = z;
}
else
{
top2--;
i++;
}
}
}
return Num[top1];
}
int main()
{
string str;
cin >> str;
str+='#';
ll sum = Cals(str);
cout << sum << endl;
return 0;
}
顺序栈
/************************************************
顺序栈类SeqStack的使用范例
*************************************************/
#include<iostream>
using namespace std;
const int StackSize = 10; //10是示例性的数据,根据实际问题具体定义
template <typename DataType>
class SeqStack
{
public:
SeqStack( ); //构造函数,初始化一个空栈
~SeqStack( ); //析构函数
void Push( DataType x ); //入栈操作,将元素x入栈
DataType Pop( ); //出栈操作,将栈顶元素弹出
DataType GetTop( ); //取栈顶元素(并不删除)
int Empty( ); //判断栈是否为空
private:
DataType data[StackSize]; //存放栈元素的数组
int top; //游标,栈顶指针,为栈顶元素在数组中的下标
};
template<typename DataType>
SeqStack<DataType>:: SeqStack()
{
top = -1;
}
template<typename DataType>
SeqStack<DataType>:: ~SeqStack()
{
}
template<typename DataType>
int SeqStack<DataType>:: Empty()
{
if(top == -1)
return 1;
else
return 0;
}
template<typename DataType>
DataType SeqStack<DataType>:: GetTop( )
{
if(top == -1)
throw "下溢异常";
else
return data[top];
}
template<typename DataType>
void SeqStack<DataType>:: Push(DataType x)
{
if (top == StackSize - 1) throw "上溢";
data[++top] = x;
}
template<typename DataType>
DataType SeqStack<DataType>:: Pop( )
{
DataType x;
if (top == -1) throw "下溢";
x = data[top--];
return x;
}
int main( )
{
int x;
SeqStack<int> S{ }; //定义顺序栈变量S
cout << "对15和10执行入栈操作,";
S.Push(15);
S.Push(10);
cout << "当前栈顶元素为:" << S.GetTop( ) << endl; //输出栈顶元素10
try
{
x = S.Pop( );
cout << "执行一次出栈操作,删除元素" << x << endl; //输出出栈元素10
}
catch(char* str)
{
cout << str << endl;
}
try
{
cout << "请输入待入栈元素:";
cin >> x;
S.Push(x);
}
catch(char* str)
{
cout << str << endl;
}
if (S.Empty( ) == 1) cout << "栈为空" << endl;
else cout << "栈非空" << endl; //栈有2个元素,输出栈非空
return 0;
}
循环队列
/*************************************************
循环队列类CirQueue的使用范例
**************************************************/
#include<iostream>
using namespace std;
const int QueueSize = 100; //100是示例性数据,根据需要重新定义
template <typename DataType>
class CirQueue
{
public:
CirQueue( ); //构造函数,初始化空队列
~ CirQueue( ); //析构函数
void EnQueue(DataType x); //入队操作,将元素x入队
DataType DeQueue( ); //出队操作,将队头元素出队
DataType GetQueue( ); //取队头元素(并不删除)
int Empty( ); //判断队列是否为空
private:
DataType data[QueueSize]; //存放队列元素的数组
int front, rear; //游标,队头和队尾指针
};
template<typename DataType>
CirQueue<DataType>:: CirQueue()
{
rear = front = QueueSize - 1;
}
template<typename DataType>
CirQueue<DataType>:: ~CirQueue()
{
}
template<typename DataType>
void CirQueue<DataType>:: EnQueue(DataType x)
{
if ((rear + 1) % QueueSize == front)
throw "上溢";
rear = (rear + 1) % QueueSize; //队尾指针在循环意义下加1
data[rear] = x; //在队尾处插入元素
}
template<typename DataType>
DataType CirQueue<DataType>:: DeQueue( )
{
if (rear == front) throw "下溢";
front = (front + 1) % QueueSize; //队头指针在循环意义下加1
return data[front]; //读取并返回出队前的队头元素
}
template<typename DataType>
DataType CirQueue<DataType>:: GetQueue( )
{
if (rear == front) throw "下溢";
return data[(front + 1) % QueueSize]; //注意不修改队头指针
}
template<typename DataType>
int CirQueue<DataType>:: Empty()
{
if(front == rear)
return 1;
else
return 0;
}
int main( )
{
int x;
CirQueue<int>Q{ }; //定义对象变量Q
cout << "对5和8执行入队操作,";
Q.EnQueue(5);
Q.EnQueue(8);
cout << "当前队头元素为:" << Q.GetQueue( ) << endl; //输出队头元素5
try
{
x = Q.DeQueue( );
cout << "执行一次出队操作,出队元素是:" << x << endl; //输出出队元素5
}
catch(char* str)
{
cout << str << endl;
}
try
{
cout <<"请输入入队元素:";
cin >> x;
Q.EnQueue(x);
}
catch(char* str)
{
cout << str << endl;
}
if (Q.Empty( ) == 1) cout << "队列为空" << endl;
else cout << "队列非空" << endl; //队列有2个元素,输出队列非空
return 0;
}
串
KMP
#include<iostream>
using namespace std;
const int N = 1e5 + 10, M = 1e6 + 10;
int n,m;
int ne[N];
char s[M],p[N];
int main()
{
cin >> n >> p + 1 >> m >> s + 1;
for(int i = 2, j = 0; i <= n; i ++ )
{
while(j&&p[i]!=p[j+1]) j = ne[j];
if(p[i]==p[j+1])j ++;
ne[i] = j;
}
for(int i = 1, j = 0; i <= m; i ++ )
{
while(j&&s[i]!=p[j+1]) j = ne[j];
if(s[i]==p[j+1]) j ++ ;
if(j == n)
{
cout << i - n << " ";
j = ne[j];
}
}
return 0;
}
八皇后问题
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
bool hen[N],up[N*2+1],down[N*2+1];
int K;
int n;
int main()
{
cin >> K;
while(K--)
{
memset(hen,0,sizeof hen);
memset(up,0,sizeof up);
memset(down,0,sizeof down);
cin >> n;
int it = true;
for(int y = 1 ; y <= n ; y ++ )
{
int x;
cin >> x;
if(hen[x]||up[x+y]||down[y-x+n]) it = false;
hen[x]=up[x+y]=down[y-x+n]=true;
}
if(it) cout <<"YES"<<endl;
else cout <<"NO"<<endl;
}
return 0;
}
发纸牌问题
/******************************
发纸牌
*******************************/
#include <iostream>
#include <ctime>//使用库函数time
#include <cstring>
using namespace std;
int sign[4][13] = {0}; //标志数组
string str1[4] = {"梅花","黑桃","红桃","方块"}; //全局变量存储花色和点数
string str2[13] = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
class PlayCard
{
public:
PlayCard( );
~PlayCard( );
void SendCards(int n);
void PrintCards( );
private:
string card[13];
int number;
};
PlayCard :: PlayCard( )
{
number = 0;
}
void PlayCard :: SendCards(int n)
{
int i, j, k;
number = n;
memset(sign, 0, n); //初始化标志数组,所有牌均未发出
srand(time(nullptr)); //初始化随机种子为当前系统时间
for (k = 0; k < n; ) //省略表达式3,发第k张牌
{
i = rand( ) % 4 ; //随机生成花色的下标
j = rand( ) % 13; //随机生成点数的下标
if (sign[i][j] == 1) //这张牌已发出
continue; //跳过循环体余下语句,注意k的值不变
else
{
card[k] =str1[i] + str2[j]; //连接str1和str2,并复制给card数组
sign[i][j] = 1; //标识这张牌已发出
k++; //准备发下一张牌
}
}
}
PlayCard :: ~PlayCard( )
{
}
void PlayCard::PrintCards( )
{
for (int k = 0; k < number; k++)
cout << card[k] << " "; //输出第k张牌
cout << endl;
}
int main( )
{
int n;
PlayCard P{ }; //创建对象变量P
cout << "请输入要发牌的张数:";
cin >> n;
P.SendCards(n); //发n张牌
P.PrintCards( ); //打印发出的牌
return 0;
}
十字链表
#include<stdio.h>
#include<stdlib.h>
typedef struct OLNode
{
int i, j, e; //矩阵三元组i代表行 j代表列 e代表当前位置的数据
struct OLNode *right, *down; //指针域 右指针 下指针
}OLNode, *OLink;
typedef struct
{
OLink *rhead, *chead; //行和列链表头指针
int mu, nu, tu; //矩阵的行数,列数和非零元的个数
}CrossList;
CrossList CreateMatrix_OL(CrossList M);
void display(CrossList M);
int main()
{
CrossList M;
M.rhead = NULL;
M.chead = NULL;
M = CreateMatrix_OL(M);
printf("输出矩阵M:\n");
display(M);
return 0;
}
CrossList CreateMatrix_OL(CrossList M)
{
int m, n, t;
int i, j, e;
OLNode *p, *q;
printf("输入矩阵的行数、列数和非0元素个数:");
scanf("%d%d%d", &m, &n, &t);
M.mu = m;
M.nu = n;
M.tu = t;
if (!(M.rhead = (OLink*)malloc((m + 1) * sizeof(OLink))) || !(M.chead = (OLink*)malloc((n + 1) * sizeof(OLink))))
{
printf("初始化矩阵失败");
exit(0);
}
for (i = 1; i <= m; i++)
{
M.rhead[i] = NULL;
}
for (j = 1; j <= n; j++)
{
M.chead[j] = NULL;
}
for (scanf("%d%d%d", &i, &j, &e); 0 != i; scanf("%d%d%d", &i, &j, &e)) {
if (!(p = (OLNode*)malloc(sizeof(OLNode))))
{
printf("初始化三元组失败");
exit(0);
}
p->i = i;
p->j = j;
p->e = e;
//链接到行的指定位置
if (NULL == M.rhead[i] || M.rhead[i]->j > j)
{
p->right = M.rhead[i];
M.rhead[i] = p;
}
else
{
for (q = M.rhead[i]; (q->right) && q->right->j < j; q = q->right);
p->right = q->right;
q->right = p;
}
//链接到列的指定位置
if (NULL == M.chead[j] || M.chead[j]->i > i)
{
p->down = M.chead[j];
M.chead[j] = p;
}
else
{
for (q = M.chead[j]; (q->down) && q->down->i < i; q = q->down);
p->down = q->down;
q->down = p;
}
}
return M;
}
void display(CrossList M) {
for (int i = 1; i <= M.nu; i++)
{
if (NULL != M.chead[i])
{
OLink p = M.chead[i];
while (NULL != p)
{
printf("%d\t%d\t%d\n", p->i, p->j, p->e);
p = p->down;
}
}
}
}
矩阵压缩
特殊矩阵的压缩存储
1.对称矩阵的压缩存储:
存n*(n+1)/2个元素
访问元素的方法:k = i (i-1)/2 + j -1.
2.三角矩阵的压缩存储:
存n(n+1)/2+1个元素
访问元素的方法:k = (i - 1)*(2n-i+2)/2+j-i
3.对角矩阵的压缩存储:
K = 2i+j-3
4.稀疏矩阵的压缩存储
树和二叉树
优先队列
#include<iostream>
using namespace std;
const int QueueSize = 100;
class PriQueue
{
public:
PriQueue();
~PriQueue();
void EnQueue(int x); //入队操作
int DeQueue();//出队操作
int GetQueue();
int Empty();
private:
int data[QueueSize];
int rear; //游标,队尾指针
};
PriQueue :: PriQueue()
{
rear = 0;
}
PriQueue :: ~PriQueue()
{
}
int PriQueue :: GetQueue()
{
return data[1];
}
int PriQueue :: Empty()
{
if(rear == 0)
return 1;
else
return 0;
}
void PriQueue :: EnQueue(int x)
{
if(rear == QueueSize - 1)
throw "上溢异常";
int temp, i;
i = ++rear;
data[i] = x;
while(i/2 > 0 && data[i/2] < x)
{
temp = data[i];
data[i] = data[i/2];
data[i/2] = temp;
i = i/2;
}
}
int PriQueue :: DeQueue()
{
if(rear == 0)
throw "上溢异常";
int temp, x, i, j; //temp用于交换变量、x用于返回值,i父节点,j孩子结点
x = data[1];
data[1] = data[rear--];
i = 1;
j = 2*i;
while(j <= rear)
{
if(j < rear && data[j] < data[j+1])
j++; //选出两者中较大的值
if(data[i] > data[j])
break;
else
{
temp = data[i];
data[i] = data[j];
data[j] = temp;
i = j;
j = 2 * i;
}
}
return x;
}
int main()
{
/** */
PriQueue p{ };
p.EnQueue(30);
p.EnQueue(22);
p.EnQueue(18);
p.EnQueue(32);
p.EnQueue(36);
p.EnQueue(45);
p.EnQueue(40);
p.EnQueue(50);
cout << "队头元素是:" << p.GetQueue() << endl;
cout << p.DeQueue();
cout << endl;
cout << p.DeQueue();
cout << endl;
cout << "出队两个元素后,队头元素是:" << p.GetQueue() << endl;
return 0;
}
二叉链表的遍历
/*************************************************
二叉链表类BiTree的使用范例
**************************************************/
#include<iostream>
using namespace std;
template<typename DataType>
struct BiNode
{
DataType data;
BiNode *lchild, *rchild;
};
template<typename DataType>
class BiTree
{
public:
BiTree( )
{
root = Creat(root); //构造函数,建立一棵二叉树
}
~BiTree( )
{
Release(root); //析构函数,释放各结点的存储空间
}
void PreOrder( )
{
PreOrder(root); //前序遍历二叉树
}
void InOrder( )
{
InOrder(root); //中序遍历二叉树
}
void PostOrder( )
{
PostOrder(root); //后序遍历二叉树
}
void LeverOrder( ); //层序遍历二叉树
private:
BiNode <DataType>*Creat(BiNode<DataType> *bt); //构造函数调用
void Release(BiNode<DataType> *bt); //析构函数调用
void PreOrder(BiNode<DataType> *bt); //前序遍历函数调用
void InOrder(BiNode<DataType> *bt); //中序遍历函数调用
void PostOrder(BiNode<DataType> *bt); //后序遍历函数调用
BiNode<DataType> *root; //指向根结点的头指针
};
template<typename DataType>
void BiTree<DataType>:: PreOrder(BiNode<DataType> *bt)
{
if (bt == nullptr) return; //递归调用的结束条件
else
{
cout << bt->data; //访问根结点bt的数据域
PreOrder(bt->lchild); //前序递归遍历bt的左子树
PreOrder(bt->rchild); //前序递归遍历bt的右子树
}
}
template<typename DataType>
void BiTree<DataType>:: InOrder(BiNode<DataType> *bt)
{
if (bt == nullptr) return; //递归调用的结束条件
else
{
InOrder(bt->lchild); //前序递归遍历bt的左子树
cout << bt->data; //访问根结点bt的数据域
InOrder(bt->rchild); //前序递归遍历bt的右子树
}
}
template<typename DataType>
void BiTree<DataType>:: PostOrder(BiNode<DataType> *bt)
{
if (bt == nullptr) return; //递归调用的结束条件
else
{
InOrder(bt->lchild); //前序递归遍历bt的左子树
InOrder(bt->rchild); //前序递归遍历bt的右子树
cout << bt->data; //访问根结点bt的数据域
}
}
template<typename DataType>
void BiTree<DataType>:: LeverOrder( )
{
BiNode<DataType> *Q[100], *q = nullptr; //顺序队列最多100个结点
int front = -1, rear = -1; //队列初始化
if (root == nullptr) return; //二叉树为空,算法结束
Q[++rear] = root; //根指针入队
while (front != rear) //当队列非空时
{
q = Q[++front]; //出队
cout << q->data;
if (q->lchild != nullptr) Q[++rear] = q->lchild;
if (q->rchild != nullptr) Q[++rear] = q->rchild;
}
}
template<typename DataType>
BiNode<DataType> *BiTree <DataType>:: Creat(BiNode<DataType> *bt)
{
char ch;
cout << "请输入扩展二叉树的前序遍历序列,每次输入一个字符:";
cin >> ch; //输入结点的数据信息,假设为字符
if (ch == '#') bt = nullptr; //建立一棵空树
else
{
bt = new BiNode<DataType>;
bt->data = ch;
bt->lchild = Creat(bt->lchild); //递归建立左子树
bt->rchild = Creat(bt->rchild); //递归建立右子树
}
return bt;
}
template<typename DataType>
void BiTree<DataType>:: Release(BiNode<DataType> *bt)
{
if (bt == nullptr) return;
else
{
Release(bt->lchild); //释放左子树
Release(bt->rchild); //释放右子树
delete bt; //释放根结点
}
}
int main( )
{
BiTree<char> T{}; //定义对象变量T
cout << "该二叉树的前序遍历序列是:";
T.PreOrder( );
cout << "\n该二叉树的中序遍历序列是:";
T.InOrder( );
cout << "\n该二叉树的后序遍历序列是:";
T.PostOrder( );
cout << "\n该二叉树的层序遍历序列是:";
T.LeverOrder( );
return 0;
}
图
邻接表
/************************************************
邻接表类ALGraph的使用范例
*************************************************/
#include<iostream>
using namespace std;
struct EdgeNode //定义边表结点
{
int adjvex; //邻接点域
EdgeNode *next;
};
template <typename DataType>
struct VertexNode //定义顶点表结点
{
DataType vertex;
EdgeNode *firstEdge;
};
const int MaxSize = 10; //图的最多顶点数
int visited[MaxSize] = {0};
template <typename DataType>
class ALGraph
{
public:
ALGraph(DataType a[ ], int n, int e); //构造函数,建立n个顶点e条边的图
~ALGraph( ); //析构函数,释放邻接表各边表结点的存储空间
void DFTraverse(int v); //深度优先遍历图
void BFTraverse(int v); //广度优先遍历图
private:
VertexNode<DataType> adjlist[MaxSize]; //存放顶点表的数组
int vertexNum, edgeNum; //图的顶点数和边数
};
template <typename DataType>
ALGraph<DataType> :: ALGraph(DataType a[ ], int n, int e)
{
int i, j, k;
EdgeNode *s = nullptr;
vertexNum = n;
edgeNum = e;
for (i = 0; i < vertexNum; i++) //输入顶点信息,初始化顶点表
{
adjlist[i].vertex = a[i];
adjlist[i].firstEdge = NULL;
}
for (k = 0; k < edgeNum; k++) //依次输入每一条边
{
cout << "输入边所依附的两个顶点的编号:";
cin >> i >> j; //输入边所依附的两个顶点的编号
s = new EdgeNode;
s->adjvex = j; //生成一个边表结点s
s->next = adjlist[i].firstEdge; //将结点s插入到第i个边表的表头
adjlist[i].firstEdge = s;
}
}
template <typename DataType>
ALGraph<DataType> :: ~ALGraph( )
{
EdgeNode *p = NULL, *q = NULL;
for (int i = 0; i < vertexNum; i++)
{
p = q = adjlist[i].firstEdge;
while (p != NULL)
{
p = p->next;
delete q;
q = p;
}
}
}
template <typename DataType>
void ALGraph<DataType> :: DFTraverse(int v)
{
int j;
EdgeNode *p = NULL;
cout << adjlist[v].vertex;
visited[v] = 1;
p = adjlist[v].firstEdge; //工作指针p指向顶点v的边表
while (p != NULL) //依次搜索顶点v的邻接点
{
j = p->adjvex;
if (visited[j] == 0) DFTraverse(j);
p = p->next;
}
}
template <typename DataType>
void ALGraph<DataType> :: BFTraverse(int v)
{
int w, j, Q[MaxSize]; //采用顺序队列
int front = -1, rear = -1; //初始化队列
EdgeNode *p = nullptr;
cout << adjlist[v].vertex;
visited[v] = 1;
Q[++rear] = v; //被访问顶点入队
while (front != rear) //当队列非空时
{
w = Q[++front];
p = adjlist[w].firstEdge; //工作指针p指向顶点v的边表
while (p != NULL)
{
j = p->adjvex;
if (visited[j] == 0)
{
cout << adjlist[j].vertex;
visited[j] = 1;
Q[++rear] = j;
}
p = p->next;
}
}
}
int main( )
{
//测试数据是图6-20(a),边是(0 1)(0 3)(0 4)(1 2)(2 4)(3 2)(3 4)
char ch[ ] = {'A','B','C','D','E'};
int i;
ALGraph<char> ALG(ch, 5, 6); //建立具有5个顶点6条边的有向图
for (i = 0; i < MaxSize; i++)
visited[i] = 0;
cout << "深度优先遍历序列是:";
ALG.DFTraverse(0); //从顶点0出发进行深度优先遍历
for (i = 0; i < MaxSize; i++)
visited[i] = 0;
cout << "广度优先遍历序列是:";
ALG.BFTraverse(0); //从顶点0出发进行广度优先遍历
return 0;
}
邻接矩阵
/************************************************
邻接矩阵类MGraph的使用范例
*************************************************/
#include<iostream>
using namespace std;
const int MaxSize = 10; //图中最多顶点个数
int visited[MaxSize] = {0}; //全局数组变量visited初始化
template <typename DataType>
class MGraph
{
public:
MGraph(DataType a[ ], int n, int e); //构造函数,建立具有n个顶点e条边的图
~MGraph( ) { }; //析构函数
void DFTraverse(int v); //深度优先遍历图
void BFTraverse(int v); //广度优先遍历图
private:
DataType vertex[MaxSize]; //存放图中顶点的数组
int edge[MaxSize][MaxSize]; //存放图中边的数组
int vertexNum, edgeNum; //图的顶点数和边数
};
template<typename DataType>
MGraph <DataType>:: MGraph(DataType a[ ], int n, int e)
{
int i, j, k;
vertexNum = n;
edgeNum = e;
for (i = 0; i < vertexNum; i++) //存储顶点
vertex[i] = a[i];
for (i = 0; i < vertexNum; i++) //初始化邻接矩阵
for (j = 0; j < vertexNum; j++)
edge[i][j] = 0;
for (k = 0; k < edgeNum; k++) //依次输入每一条边
{
cout << "请输入边依附的两个顶点的编号:";
cin >> i >> j; //输入边依附的两个顶点的编号
edge[i][j] = 1;
edge[j][i] = 1; //置有边标志
}
}
template<typename DataType>
void MGraph <DataType>:: DFTraverse(int v)
{
cout << vertex[v];
visited[v] = 1;
for (int j = 0; j < vertexNum; j++)
if (edge[v][j] == 1 && visited[j] == 0) DFTraverse( j );
}
template<typename DataType>
void MGraph <DataType>:: BFTraverse(int v)
{
int w, j, Q[MaxSize]; //采用顺序队列
int front = -1, rear = -1; //初始化队列
cout << vertex[v];
visited[v] = 1;
Q[++rear] = v; //被访问顶点入队
while (front != rear) //当队列非空时
{
w = Q[++front]; //将队头元素出队并送到v中
for (j = 0; j < vertexNum; j++)
if (edge[w][j] == 1 && visited[j] == 0 )
{
cout << vertex[j];
visited[j] = 1;
Q[++rear] = j;
}
}
}
int main( )
{
int i;
char ch[ ]= {'A','B','C','D','E'};
/* 测试数据六条边是:(0 1)(0 2)(0 3)(0 4)(1 2)(2 4) */
MGraph<char> MG{ch, 5, 6}; //建立具有5个顶点6条边的无向图
for (i = 0; i < MaxSize; i++)
visited[i] = 0;
cout << "深度优先遍历序列是:" << endl;
MG.DFTraverse(0); //从顶点0出发进行深度优先遍历
for (i = 0; i < MaxSize; i++)
visited[i] = 0;
cout << "广度优先遍历序列是:" << endl;
MG.BFTraverse(0); //从顶点0出发进行广度优先遍历
return 0;
}
查找
二叉排序树
#include<iostream>
using namespace std;
struct BiNode
{
int data;
BiNode *lchild, *rchild;
};
class BiSortTree
{
public:
BiSortTree(int a[ ], int n); //建立查找集合a[n]的二叉排序树
~ BiSortTree( )
{
Release(root); //析构函数,同二叉链表的析构函数
}
void InOrder( )
{
InOrder(root); //中序遍历二叉树
}
int GetDepth();
BiNode *InsertBST(int x)
{
return InsertBST(root, x); //插入记录x
}
void DeleteBST(BiNode *p, BiNode *f ); //删除f的左孩子p
BiNode *SearchBST(int k)
{
return SearchBST(root, k); //查找值为k的结点
}
private:
int GetDepth(BiNode *&bt);
void Release(BiNode *bt);
BiNode *InsertBST(BiNode *bt, int x);
BiNode *SearchBST(BiNode*bt, int k);
void InOrder(BiNode *bt); //中序遍历函数调用
BiNode *root; //二叉排序树的根指针
};
void BiSortTree :: InOrder(BiNode *bt)
{
if (bt == nullptr)
return; //递归调用的结束条件
else
{
InOrder(bt->lchild); //前序递归遍历bt的左子树
cout << bt->data << " "; //访问根结点bt的数据域
InOrder(bt->rchild); //前序递归遍历bt的右子树
}
}
BiNode * BiSortTree :: SearchBST(BiNode *bt, int k)
{
if (bt == nullptr)
return nullptr;
if (bt->data == k)
return bt;
else if (bt->data > k)
return SearchBST(bt->lchild, k);
else
return SearchBST(bt->rchild, k);
}
BiNode *BiSortTree::InsertBST(BiNode*bt, int x)
{
if (bt == nullptr) //找到插入位置
{
BiNode *s = new BiNode;
s->data = x;
s->lchild = nullptr;
s->rchild = nullptr;
bt = s;
return bt;
}
else if (bt->data > x)
bt->lchild = InsertBST(bt->lchild, x);
else
bt->rchild = InsertBST(bt->rchild, x);
}
BiSortTree::BiSortTree(int a[ ], int n)
{
root = nullptr;
for (int i = 0; i < n; i++)
root = InsertBST(root, a[i]);
}
void BiSortTree::DeleteBST(BiNode *p, BiNode *f )
{
if ((p->lchild == nullptr) && (p->rchild == nullptr)) //p为叶子
{
f->lchild = nullptr;
delete p;
return;
}
if (p->rchild == nullptr) //p只有左子树
{
f->lchild = p->lchild;
delete p;
return;
}
if (p->lchild == nullptr) //p只有右子树
{
f->lchild = p->rchild;
delete p;
return;
}
BiNode *par = p, *s = p->rchild; //p的左右子树均不空
while (s->lchild != nullptr) //查找最左下结点
{
par = s;
s = s->lchild;
}
p->data = s->data;
if (par == p)
par->rchild = s->rchild; //特殊情况,p的右孩子无左子树
else
par->lchild = s->rchild;
delete s;
}
void BiSortTree:: Release(BiNode *bt)
{
if (bt == nullptr)
return;
else
{
Release(bt->lchild); //释放左子树
Release(bt->rchild); //释放右子树
delete bt; //释放根结点
}
}
int BiSortTree::GetDepth()
{
int nMax = GetDepth(root);
return nMax;
}
int BiSortTree::GetDepth(BiNode *&bt)
{
if(nullptr == bt) return 0;
int nL = GetDepth(bt->lchild);
int nR = GetDepth(bt->rchild);
int nMax = nL > nR ? nL : nR;
nMax += 1;
return nMax;
}
int main( )
{
BiNode *p = nullptr;
int arr[10] = {1,2, 3, 4, 5, 6, 7, 8, 9, 10};
BiSortTree B{arr,10};
B.InOrder();
int key;
cout << "请输入查找的元素值";
cin >> key;
p = B.SearchBST(key);
if (p != nullptr)
cout << p->data << endl;
else
cout << "查找失败" << endl;
cout<<B.GetDepth() << endl;
system("pause");
return 0;
}
平衡二叉树
/***************************************************************
二叉排序树的类定义、成员函数定义及使用范例
****************************************************************/
#include<iostream>
using namespace std;
typedef struct biNode
{
int data;
biNode *lchild, *rchild;
}*BiNode,BiNodes;
struct biNode biNode = {0x3f,NULL,NULL};
class BiSortTree
{
public:
BiSortTree(int a[ ], int n); //建立查找集合a[n]的二叉排序树
~ BiSortTree( )
{
Release(root); //析构函数,同二叉链表的析构函数
}
void InOrder( )
{
InOrder(root); //中序遍历二叉树
}
bool InsertBST(int x);
int GetDepth();
void DeleteBST(BiNode p, BiNode f ); //删除f的左孩子p
BiNode SearchBST(int k)
{
return SearchBST(root, k); //查找值为k的结点
}
private:
void Release(BiNode bt);
int GetDepth(BiNode &bt);
bool InsertBST(BiNode &bt, int x);
BiNode SearchBST(BiNode bt, int k);
void InOrder(BiNode bt); //中序遍历函数调用
BiNode root; //二叉排序树的根指针
//平衡函数
void SingRotateLeft(BiNode &pK2);//LL
void SingRotateRight(BiNode &pK2);//RR
void DoubleRotateLR(BiNode &pK);//LR
void DoubleRotateRL(BiNode &pK);//RL
};
void BiSortTree :: InOrder(BiNode bt)
{
if (bt == nullptr)
return; //递归调用的结束条件
else
{
InOrder(bt->lchild); //前序递归遍历bt的左子树
cout << bt->data << " "; //访问根结点bt的数据域
InOrder(bt->rchild); //前序递归遍历bt的右子树
}
}
BiNode BiSortTree :: SearchBST(BiNode bt, int k)
{
if (bt == nullptr)
return nullptr;
if (bt->data == k)
return bt;
else if (bt->data > k)
return SearchBST(bt->lchild, k);
else
return SearchBST(bt->rchild, k);
}
/********************
最核心的部分,
因为参数是指针的引用,
在每次插入元素过后,
回溯的时候都会对当前结点的左右子树的深度进行判定。
*********************/
bool BiSortTree::InsertBST(BiNode &bt, int x)
{
if (bt == nullptr) //找到插入位置
{
BiNodes *s = new BiNodes;
s->data = x;
s->lchild = nullptr;
s->rchild = nullptr;
bt = s;
return true;
}
if(x > bt->data)
{
InsertBST(bt->rchild,x);
if(GetDepth(bt->rchild)-GetDepth(bt->lchild)==2)
if(GetDepth(bt->rchild->lchild)>GetDepth(bt->rchild->rchild))
DoubleRotateRL(bt);
else SingRotateLeft(bt);
}
if(x < bt->data)
{
InsertBST(bt->lchild,x);
if(GetDepth(bt->lchild)-GetDepth(bt->rchild)==2)//????
if(GetDepth(bt->lchild->rchild)>GetDepth(bt->lchild->lchild))
DoubleRotateLR(bt);
else SingRotateRight(bt);
}
}
bool BiSortTree::InsertBST(int x)
{
if(InsertBST(root,x))return true;
return false;
}
BiSortTree::BiSortTree(int a[ ], int n)
{
root = nullptr;
for (int i = 0; i < n; i++)
InsertBST(root, a[i]);
}
void BiSortTree::DeleteBST(BiNode p, BiNode f )
{
if ((p->lchild == nullptr) && (p->rchild == nullptr)) //p为叶子
{
f->lchild = nullptr;
delete p;
return;
}
if (p->rchild == nullptr) //p只有左子树
{
f->lchild = p->lchild;
delete p;
return;
}
if (p->lchild == nullptr) //p只有右子树
{
f->lchild = p->rchild;
delete p;
return;
}
BiNode par = p, s = p->rchild; //p的左右子树均不空
while (s->lchild != nullptr) //查找最左下结点
{
par = s;
s = s->lchild;
}
p->data = s->data;
if (par == p)
par->rchild = s->rchild; //特殊情况,p的右孩子无左子树
else
par->lchild = s->rchild;
delete s;
}
void BiSortTree :: Release(BiNode bt)
{
if (bt == nullptr)
return;
else
{
Release(bt->lchild); //释放左子树
Release(bt->rchild); //释放右子树
delete bt; //释放根结点
}
}
int BiSortTree::GetDepth()
{
int nMax = GetDepth(root);
return nMax;
}
int BiSortTree::GetDepth(BiNode &bt)
{
if(nullptr == bt) return 0;
int nL = GetDepth(bt->lchild);
int nR = GetDepth(bt->rchild);
int nMax = nL > nR ? nL : nR;
nMax += 1;
return nMax;
}
/***
RR
***/
void BiSortTree::SingRotateLeft(BiNode &bt2)
{
BiNode bt1 = bt2 -> rchild;
bt2 -> rchild = bt1->lchild;
bt1 -> lchild = bt2;
bt2 = bt1;
}
/***
LL
***/
void BiSortTree::SingRotateRight(BiNode &bt2)
{
BiNode bt1 = bt2 -> lchild;
bt2 -> lchild = bt1->rchild;
bt1 -> rchild = bt2;
bt2 = bt1;
}
/***
RL
***/
void BiSortTree::DoubleRotateRL(BiNode &bt3)
{
SingRotateRight(bt3 -> rchild);
SingRotateLeft(bt3);
}
/***
LR
***/
void BiSortTree::DoubleRotateLR(BiNode &bt3)
{
SingRotateLeft(bt3->lchild);
SingRotateRight(bt3);
}
int main( )
{
int arr[10] = {1,2, 3, 4, 5, 6, 7, 8, 9, 10};
BiSortTree B{arr,10};
B.InOrder();
cout << B.GetDepth()<<endl;;
return 0;
}
排序
桶排序
#include <iostream>
#include <cstring>
using namespace std;
void bucketSort(int* a, int n, int max)
{
int i, j;
int *buckets;
if (a==NULL || n<1 || max<1)
return ;
// 创建一个容量为max的数组buckets,并且将buckets中的所有数据都初始化为0。
if ((buckets = new int[max])==NULL)
return ;
memset(buckets, 0, max*sizeof(int));
// 1. 计数
for(i = 0; i < n; i++)
buckets[a[i]]++;
// 2. 排序
for (i = 0, j = 0; i < max; i++)
while( (buckets[i]--) >0 )
a[j++] = i;
delete[] buckets;
}
int main()
{
int i;
int a[] = {8,2,3,4,3,6,6,3,9};
int ilen = (sizeof(a)) / (sizeof(a[0]));
cout << "before sort:";
for (i=0; i<ilen; i++)
cout << a[i] << " ";
cout << endl;
bucketSort(a, ilen, 10); // 桶排序
cout << "after sort:";
for (i=0; i<ilen; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}