第四章 栈和队列

栈的基本操作

顺序栈

头文件:
sq_stack_test.h

#include<iostream>
#include<string>

using namespace std;

const int SIZE=100;
typedef int elem_type;

//定义栈
typedef struct{
    int *elem;
    int top;
    int size;
}sq_stack;

void error_message(string s);//提示错误信息
void increment(sq_stack &s);//加长栈空间
void sq_stack_init(sq_stack &s);//初始化栈
void sq_stack_clear(sq_stack &s);//清空栈
void sq_stack_destroy(sq_stack &s);//销毁栈
void sq_stack_push(sq_stack &s,elem_type e);//入栈
void sq_stack_pop(sq_stack &s,elem_type &e);//出栈
void get_sq_stack_top(sq_stack s,elem_type &e);//获取栈顶元素
int sq_stack_length(sq_stack s);//栈长度
bool sq_stack_empty(sq_stack s);//判断栈空
bool sq_stack_full(sq_stack s);//判断栈满
void sq_stack_traverse(sq_stack s);//遍历输出栈

void error_message(string s){
    cout<<s<<endl;
}

//加长栈空间
void increment(sq_stack &s){
    int *p=new int[SIZE+s.size];
    if(!p) error_message("内存分配失败");
    for(int i=0;i<=s.top;i++)
        p[i]=s.elem[i];
    delete s.elem;
    s.elem=p;
    s.size+=SIZE;
}

//初始化栈
void sq_stack_init(sq_stack &s){
    s.elem=new int[SIZE];
    if(!s.elem) error_message("内存分配失败");
    s.top=-1;
    s.size=SIZE;
}

//销毁栈
void sq_stack_destroy(sq_stack &s){
    delete s.elem;
}

//清空栈
void sq_stack_clear(sq_stack &s){
    s.top=-1;
}

//进栈
void sq_stack_push(sq_stack &s,elem_type e){
    if(s.top+1>=s.size){
        increment(s);
    }
    s.elem[++s.top]=e;
}

//出栈
void sq_stack_pop(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能出栈"<<endl;
        return ;
    }
    e=s.elem[s.top--];
}

//获取栈顶元素
void get_sq_stack_top(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能获取栈顶元素"<<endl;
        return ;
    }
    e=s.elem[s.top];
}

//计算栈的长度
int sq_stack_length(sq_stack s){
    return s.top+1;
}

//判断栈是否空
bool sq_stack_empty(sq_stack s){
    return s.top+1==0;
}

//判断栈是否满
bool sq_stack_full(sq_stack s){
    return s.top+1==s.size;
}

void sq_stack_traverse(sq_stack s){
    elem_type e;
    while(!sq_stack_empty(s)){
        sq_stack_pop(s,e);
        cout<<e<<" ";
    }
    cout<<endl;
}

主函数:
#include"sq_stack_test.h"


int main()
{
    sq_stack stack;
    sq_stack_init(stack);
    for(int i=1;i<=6;i++){
        sq_stack_push(stack,i);
        cout<<i<<"进栈,栈大小为"<<sq_stack_length(stack)<<",栈内容:";sq_stack_traverse(stack);
    }
    cout<<endl;
    int e;
    while(stack.top!=-1){
        sq_stack_pop(stack,e);
        cout<<e<<"出栈,栈大小为"<<sq_stack_length(stack)<<",栈内容:";sq_stack_traverse(stack);
    }
    return 0;
}

链栈

头文件:link_stack_test.h

#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;

typedef int elem_type;

typedef struct Node1{
    elem_type data;
    struct Node1 *next;
}node;

typedef struct Node2{
    int size;
    node *top;
}link_stack;

void error_message(string s);//错误信息输出提示
void link_stack_init(link_stack &s);//链栈初始化
void link_stack_clear(link_stack &s);//清空栈
void link_stack_destroy(link_stack &s);//销毁栈
void link_stack_push(link_stack &s,elem_type e);//入栈
void link_stack_pop(link_stack &s,elem_type &e);//出栈
bool link_stack_empty(link_stack s);//判断栈空
void link_stack_traverse(link_stack s);//遍历栈



void error_message(string s){
    cout<<s<<endl;
    exit(-1);
}
void link_stack_init(link_stack &s){
    s.size=0;
    s.top=new node;
    if(!s.top) error_message("内存分配失败");
    s.top->next=nullptr;
}

void link_stack_clear(link_stack &s){
    node *p=s.top->next;
    node *q=nullptr;
    while(p){
        q=p->next;
        delete p;
        p=q;
    }
    s.top->next=nullptr;
    s.size=0;
}

void link_stack_destroy(link_stack &s){
    node *p=s.top->next;
    node *q=nullptr;
    while(p){
        q=p->next;
        delete p;
        p=q;
    }
    delete s.top;
}

void link_stack_push(link_stack &s,elem_type e){
    node *tmp=new node;
    if(!tmp) error_message("内存分配失败");
    tmp->data=e;
    tmp->next=s.top->next;
    s.top->next=tmp;
    s.size++;
}

void link_stack_pop(link_stack &s,elem_type &e){
    if(s.top->next==nullptr) {cout<<"栈已空,不能取栈顶元素"<<endl;return;}
    e=s.top->next->data;
    node *p=s.top->next;
    s.top->next=p->next;
    delete p;
    s.size--;
}

bool link_stack_empty(link_stack s){
    return s.size==0;
}

void link_stack_traverse(link_stack s){
    node *p=s.top->next;
    while(p){
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}

主函数部分:
#include"link_stack_test.h"

int main()
{
    link_stack s;
    link_stack_init(s);
    for(int i=1;i<=6;i++){
        cout<<i<<"入栈";link_stack_push(s,i);cout<<",栈大小:"<<s.size<<",栈内容:";link_stack_traverse(s);
    }
    cout<<(link_stack_empty(s)?"栈已空":"栈不空")<<endl;
    for(int i=1;i<=6;i++){
        int e;
        link_stack_pop(s,e);
        cout<<e<<"出栈"<<",栈大小:"<<s.size<<",栈内容:";link_stack_traverse(s);
    }
    cout<<(link_stack_empty(s)?"栈已空":"栈不空")<<endl;
    link_stack_destroy(s);
    return 0;
}

栈的应用举例

  1. 背包问题
#include<iostream>
#include<string>
#include<cstring>
using namespace std;

typedef int elem_type;
const int SIZE=100;

void error_message(string s){
    cout<<s<<endl;
}

//定义栈
typedef struct{
    elem_type *elem;
    int top;
    int size;
}sq_stack;

//加长栈空间
void increment(sq_stack &s){
    elem_type *p=new elem_type[SIZE+s.size];
    if(!p) error_message("内存分配失败");
    for(int i=0;i<=s.top;i++)
        p[i]=s.elem[i];
    delete s.elem;
    s.elem=p;
    s.size+=SIZE;
}

//初始化栈
void sq_stack_init(sq_stack &s){
    s.elem=new elem_type[SIZE];
    if(!s.elem) error_message("内存分配失败");
    s.top=-1;
    s.size=SIZE;
}

//进栈
void sq_stack_push(sq_stack &s,int e){
    if(s.top+1>=s.size){
        increment(s);
    }
    s.elem[++s.top]=e;
}

//出栈
void sq_stack_pop(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能出栈"<<endl;
        return ;
    }
    e=s.elem[s.top--];
}

//获取栈顶元素
void get_sq_stack_top(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能获取栈顶元素"<<endl;
        return ;
    }
    e=s.elem[s.top];
}

//计算栈的长度
int sq_stack_length(sq_stack &s){
    return s.top+1;
}

//判断栈是否空
bool sq_stack_empty(sq_stack s){
    return s.top+1==0;
}

//遍历栈
void sq_stack_traverse(sq_stack s){
    elem_type e;
    while(!sq_stack_empty(s)){
        sq_stack_pop(s,e);
        cout<<e<<" ";
    }
    cout<<endl;
}

//背包问题,返回物品编号(从0开始编号)
//思想过程可以参考严蔚敏《数据结构及应用算法教程》
void knapsack(int w[],int T,int n){
    sq_stack s;
    sq_stack_init(s);
    int k=0;
    do{
        while(k<n && T>0){
            if(T-w[k]>=0){
                sq_stack_push(s,k);
                T-=w[k];
            }
            k++;
        }
        if(T==0) sq_stack_traverse(s);
        sq_stack_pop(s,k); T+=w[k];
        k++;
    }while(!sq_stack_empty(s) || k<n);
}

int main()
{
    int w[6]={1,8,4,3,5,2};
    knapsack(w,10,6);
    return 0;
}

  1. 表达式值
// 栈实例(表达式值),以二元运算符为例写本程序
//本程序功能:实现后缀表达式求值。
//下面的例子中,X表示乘号
//中缀表达式:aXb+(c-d/e)Xf
//前缀表达式:+XabX-c/def
//后缀表达式:abXcde/-fX+

#include<iostream>
#include<string>
#include<cstring>
using namespace std;

typedef int elem_type;
const int SIZE=100;

void error_message(string s){
    cout<<s<<endl;
}

//定义栈
typedef struct{
    elem_type *elem;
    int top;
    int size;
}sq_stack;

//加长栈空间
void increment(sq_stack &s){
    elem_type *p=new elem_type[SIZE+s.size];
    if(!p) error_message("内存分配失败");
    for(int i=0;i<=s.top;i++)
        p[i]=s.elem[i];
    delete s.elem;
    s.elem=p;
    s.size+=SIZE;
}

//初始化栈
void sq_stack_init(sq_stack &s){
    s.elem=new elem_type[SIZE];
    if(!s.elem) error_message("内存分配失败");
    s.top=-1;
    s.size=SIZE;
}

//进栈
void sq_stack_push(sq_stack &s,int e){
    if(s.top+1>=s.size){
        increment(s);
    }
    s.elem[++s.top]=e;
}

//出栈
void sq_stack_pop(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能出栈"<<endl;
        return ;
    }
    e=s.elem[s.top--];
}

//获取栈顶元素
void get_sq_stack_top(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能获取栈顶元素"<<endl;
        return ;
    }
    e=s.elem[s.top];
}

//计算栈的长度
int sq_stack_length(sq_stack &s){
    return s.top+1;
}

//判断栈是否空
bool sq_stack_empty(sq_stack s){
    return s.top+1==0;
}

//遍历栈
void sq_stack_traverse(sq_stack s){
    elem_type e;
    while(!sq_stack_empty(s)){
        sq_stack_pop(s,e);
        cout<<e<<" ";
    }
    cout<<endl;
}

//后缀表达式输出运算结果

//判断是否是运算符
bool is_operator(char c){
    if(c=='+' || c=='-' || c=='X' || c=='/')
        return true;
    return false;
}
//实现加减乘除操作
int calculate(int a,char oper,int b){
    if(oper=='+') return a+b;
    if(oper=='-') return a-b;
    if(oper=='X') return a*b;
    if(oper=='/') return a/b;
}
//思想:是数就入栈,是运算符就弹出两个数进行运算,运算结果入栈
int evaluation(char suffix[]){
    sq_stack s;
    sq_stack_init(s);
    char *ch=suffix;
    char c=*ch++;
    while(c!='#'){
        if(!is_operator(c)) sq_stack_push(s,c-'0');
        else{
            int e1,e2;
            sq_stack_pop(s,e1);sq_stack_pop(s,e2);
            sq_stack_push(s,calculate(e2,c,e1));    //此处注意要把后出栈的e2放在前面
            //cout<<calculate(e2,c,e1)<<endl;
        }
        c=*ch++;
    }
    int e3;
    sq_stack_pop(s,e3);
    return e3;
}

int main()
{
    char suffix[50]="23X452/-3X+#"; //不要忘记这个#
    cout<<"23X452/-3X+"<<endl;
    cout<<"上面表达式结果:";
    cout<<evaluation(suffix)<<endl;
    return 0;
}

  1. 括号匹配
#include<iostream>
#include<string>
#include<cstring>
using namespace std;

typedef char elem_type;
const int SIZE=100;

void error_message(string s){
    cout<<s<<endl;
}

//定义栈
typedef struct{
    elem_type *elem;
    int top;
    int size;
}sq_stack;

//加长栈空间
void increment(sq_stack &s){
    elem_type *p=new elem_type[SIZE+s.size];
    if(!p) error_message("内存分配失败");
    for(int i=0;i<=s.top;i++)
        p[i]=s.elem[i];
    delete s.elem;
    s.elem=p;
    s.size+=SIZE;
}

//初始化栈
void sq_stack_init(sq_stack &s){
    s.elem=new elem_type[SIZE];
    if(!s.elem) error_message("内存分配失败");
    s.top=-1;
    s.size=SIZE;
}

//进栈
void sq_stack_push(sq_stack &s,int e){
    if(s.top+1>=s.size){
        increment(s);
    }
    s.elem[++s.top]=e;
}

//出栈
void sq_stack_pop(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能出栈"<<endl;
        return ;
    }
    e=s.elem[s.top--];
}

//获取栈顶元素
void get_sq_stack_top(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能获取栈顶元素"<<endl;
        return ;
    }
    e=s.elem[s.top];
}

//计算栈的长度
int sq_stack_length(sq_stack &s){
    return s.top+1;
}

//判断栈是否空
bool sq_stack_empty(sq_stack s){
    return s.top+1==0;
}

//括号匹配检验
void matching(char str[]){
    bool flag=1;
    char *p=str;
    char c=*p++;
    sq_stack s;
    sq_stack_init(s);
    while(c!='#' && flag){
        switch(c){
        case '(':
        case '[': sq_stack_push(s,c);break;
        case ')':{
                    char e;
                    get_sq_stack_top(s,e);
                    if(!sq_stack_empty(s) && e=='('){
                        sq_stack_pop(s,e);
                    }
                    else{
                        flag=0;
                    }
                    break;
                 }
        case ']':{
                    char e;
                    get_sq_stack_top(s,e);
                    if(!sq_stack_empty(s) && e=='['){
                        sq_stack_pop(s,e);
                    }
                    else{
                        flag=0;
                    }
                    break;
                 }
        }
        c=*p++;
    }
    if(flag && sq_stack_empty(s)) cout<<"括号匹配无误"<<endl;
    else cout<<"括号匹配有误"<<endl;
}

int main()
{
    //括号匹配检验
    char str1[]="([()])#";
    char str2[]="([)#";
    cout<<"括号匹配检验: ";
    for(int i=0;i<strlen(str1);i++)
        cout<<str1[i];
    cout<<endl;
    matching(str1);
    cout<<endl;
    cout<<"括号匹配检验: ";
    for(int i=0;i<strlen(str2);i++)
        cout<<str2[i];
    cout<<endl;
    matching(str2);
    return 0;
}
  1. 实现递归
#include<iostream>
#include<string>
#include<cstring>
#include<map>
using namespace std;

typedef struct{
    int n,x,y;
} elem_type;
const int SIZE=100;

void error_message(string s){
    cout<<s<<endl;
}

//定义栈
typedef struct{
    elem_type *elem;
    int top;
    int size;
}sq_stack;

//加长栈空间
void increment(sq_stack &s){
    elem_type *p=new elem_type[SIZE+s.size];
    if(!p) error_message("内存分配失败");
    for(int i=0;i<=s.top;i++)
        p[i]=s.elem[i];
    delete s.elem;
    s.elem=p;
    s.size+=SIZE;
}

//初始化栈
void sq_stack_init(sq_stack &s){
    s.elem=new elem_type[SIZE];
    if(!s.elem) error_message("内存分配失败");
    s.top=-1;
    s.size=SIZE;
}

//进栈
void sq_stack_push(sq_stack &s,elem_type e){
    if(s.top+1>=s.size){
        increment(s);
    }
    s.elem[++s.top]=e;
}

//出栈
void sq_stack_pop(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能出栈"<<endl;
        return ;
    }
    e=s.elem[s.top--];
}

//获取栈顶元素
bool get_sq_stack_top(sq_stack &s,elem_type &e){
    if(s.top==-1){
        return false;
    }
    e=s.elem[s.top];
    return true;
}

//计算栈的长度
int sq_stack_length(sq_stack &s){
    return s.top+1;
}

//判断栈是否空
bool sq_stack_empty(sq_stack s){
    return s.top+1==0;
}

//中缀表达式转后缀表达式
//优先数,#:-1,(:0,+:1,-:1,):2,*:2,/:2,乘幂:3

//判断是否是运算符
bool is_operator(char c){
    if(c=='+' || c=='-' || c=='X' || c=='/' || c=='#' || c=='(' || c==')')
        return true;
    return false;
}
//判断运算符优先等级
bool precede(char c1,char c2){
    map<char ,int>mp;
    mp['#']=-1;
    mp['(']=0;
    mp['+']=mp['-']=1;
    mp['X']=mp['/']=2;
    if(mp[c1]>=mp[c2]) return true;
    return false;
}

//ackerman函数用栈实现递归
/*
            x+1,   n=0;
            x,     n=1,y=0;
            0,     n=2,y=0;
A(n,x,y)=   1,     n=3,y=0;
            2,     n>=4,y=0;
            A(n-1,A(n,x,y-1),x), n!=0,y!=0
*/
int value(int n,int x,int y){
    if(n==0) return x+1;
    else switch(n){
    case 1: return x;
    case 2: return 0;
    case 3: return 1;
    default: return 2;
    }
}
int ackerman(int n,int x,int y){
    sq_stack s;
    sq_stack_init(s);
    elem_type e;
    int u;
    e.n=n;e.x=x;e.y=y;
    sq_stack_push(s,e);
    cout<<"进栈:"<<e.n<<" "<<e.x<<" "<<e.y<<endl;
    do{
        get_sq_stack_top(s,e);
        while(e.n!=0 && e.y!=0){
            e.y--;
            sq_stack_push(s,e);
            cout<<"进栈:"<<e.n<<" "<<e.x<<" "<<e.y<<endl;
        }
        sq_stack_pop(s,e);
        cout<<"出栈:"<<e.n<<" "<<e.x<<" "<<e.y<<endl;
        u=value(e.n,e.x,e.y);
        if(!sq_stack_empty(s)){
            sq_stack_pop(s,e);
            cout<<"出栈:"<<e.n<<" "<<e.x<<" "<<e.y<<endl;
            e.n--;e.y=e.x;e.x=u;
            sq_stack_push(s,e);
            cout<<"进栈:"<<e.n<<" "<<e.x<<" "<<e.y<<endl;
        }
    }while(!sq_stack_empty(s));
    return u;
}

int main()
{
    cout<<"计算arckerman函数,以A(3,2,1)为例"<<endl;
    int result=ackerman(3,2,1);
    cout<<"A(3,2,1)="<<result<<endl;
    return 0;
}
  1. 中转后缀
#include<iostream>
#include<string>
#include<cstring>
#include<map>
using namespace std;

typedef char elem_type;
const int SIZE=100;

void error_message(string s){
    cout<<s<<endl;
}

//定义栈
typedef struct{
    elem_type *elem;
    int top;
    int size;
}sq_stack;

//加长栈空间
void increment(sq_stack &s){
    elem_type *p=new elem_type[SIZE+s.size];
    if(!p) error_message("内存分配失败");
    for(int i=0;i<=s.top;i++)
        p[i]=s.elem[i];
    delete s.elem;
    s.elem=p;
    s.size+=SIZE;
}

//初始化栈
void sq_stack_init(sq_stack &s){
    s.elem=new elem_type[SIZE];
    if(!s.elem) error_message("内存分配失败");
    s.top=-1;
    s.size=SIZE;
}

//进栈
void sq_stack_push(sq_stack &s,int e){
    if(s.top+1>=s.size){
        increment(s);
    }
    s.elem[++s.top]=e;
}

//出栈
void sq_stack_pop(sq_stack &s,elem_type &e){
    if(s.top==-1){
        cout<<"栈已空,不能出栈"<<endl;
        return ;
    }
    e=s.elem[s.top--];
}

//获取栈顶元素
bool get_sq_stack_top(sq_stack &s,elem_type &e){
    if(s.top==-1){
        return false;
    }
    e=s.elem[s.top];
    return true;
}

//计算栈的长度
int sq_stack_length(sq_stack &s){
    return s.top+1;
}

//判断栈是否空
bool sq_stack_empty(sq_stack s){
    return s.top+1==0;
}

//中缀表达式转后缀表达式
//优先数,#:-1,(:0,+:1,-:1,):2,*:2,/:2,乘幂:3

//判断是否是运算符
bool is_operator(char c){
    if(c=='+' || c=='-' || c=='X' || c=='/' || c=='#' || c=='(' || c==')')
        return true;
    return false;
}
//判断运算符优先等级
bool precede(char c1,char c2){
    map<char ,int>mp;
    mp['#']=-1;
    mp['(']=0;
    mp['+']=mp['-']=1;
    mp['X']=mp['/']=2;
    if(mp[c1]>=mp[c2]) return true;
    return false;
}
void transform(char exp[],char suffix[]){
    sq_stack s;
    sq_stack_init(s);
    sq_stack_push(s,'#');
    char *p=exp;
    char ch=*p;
    int k=0;
    while(!sq_stack_empty(s)){
        if(!is_operator(ch)) suffix[k++]=ch;
        else{
            switch(ch){
            case '(': sq_stack_push(s,ch);break;
            case ')': {
                        char ch;
                        sq_stack_pop(s,ch);
                        while(ch!='('){
                            suffix[k++]=ch;
                            sq_stack_pop(s,ch);
                        }
                        break;
                      }
            default:{
                        char c;
                        while(get_sq_stack_top(s,c) && precede(c,ch)){
                            suffix[k++]=c;
                            sq_stack_pop(s,c);
                        }//将栈中所有优先数不小于当前运算符优先数的运算符发送给后缀式
                        if(ch!='#') sq_stack_push(s,ch);
                        break;
                    }
            }
        }
        if(ch!='#') ch=*++p;
    }
    suffix[k]='\0';
}

int main()
{
    char exp[]="a+(b+(c/d-e))Xf#";
    char suffix[100];
    transform(exp,suffix);
    for(int i=0;i<strlen(suffix);i++)
        cout<<suffix[i];
    cout<<endl;
    return 0;
}

队列(链队列)

链队列基本操作

#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;

typedef int elem_type;

typedef struct Node{
    elem_type data;
    struct Node *next;
}node,*linklist;

typedef struct{
    node *front;
    node *rear;
}queue;

void error_message(string s){
    cout<<s<<endl;
    exit(-1);
}

void queue_init(queue &que){
    que.rear=que.front=new node;
    if(que.front==nullptr) error_message("内存分配失败");
    que.front->next=nullptr;
}

void queue_destroy(queue &que){
    while(que.front){
        que.rear=que.front->next;
        delete que.front;
        que.front=que.rear;
    }
}

void queue_push(queue &que,elem_type e){
    node *p=new node;
    if(!p) error_message("内存分配失败");
    p->data=e;
    p->next=nullptr;
    que.rear->next=p;
    que.rear=p;
}

bool queue_pop(queue &que,elem_type &e){
    if(que.front==que.rear) return false;
    node *p=que.front->next;
    e=p->data;
    que.front->next=p->next;
    if(que.rear==p) que.rear=que.front;
    delete p;
    return true;
}

void queue_get_front(queue que,elem_type &e){
    if(que.front->next==nullptr){
        cout<<"队列已空,无法获取队头"<<endl;
    }
    e=que.front->data;
}

void queue_traverse(queue que){
    while(que.front->next){
        cout<<que.front->next->data<<" ";
        que.front=que.front->next;
    }
    cout<<endl;
}

int main()
{
    queue que;
    queue_init(que);
    cout<<"queue:";
    for(int i=1;i<=6;i++)
        queue_push(que,i);
    queue_traverse(que);
    while(que.front->next!=nullptr){
        elem_type e;
        queue_pop(que,e);
        cout<<e<<"出队后,queue:";queue_traverse(que);
    }
    queue_destroy(que);
    return 0;
}

循环队列基本操作及杨辉三角和子集划分

// 若能估算出所需队列的大小,可以用循环队列
// 若不能估算出所需队列大小,应该用链队列,循环队列扩容费时间

#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;

const int SIZE=100;
typedef int elem_type;

typedef struct{
    elem_type *elem;
    int front;
    int rear;
    int size;
}circle_queue;

void error_message(string s){
    cout<<s<<endl;
    exit(-1);
}

void circle_queue_increment(circle_queue &que){
    elem_type *p=new elem_type[SIZE+que.size];
    if(!p) error_message("内存分匹配失败");
    for(int i=0;i<que.size-1;i++){
        p[i]=que.elem[(que.front+i)%que.size];
    }
    delete[] que.elem;
    que.elem=p;
    que.front=0;
    que.rear=que.size-1;
    que.size+=SIZE;
}

void circle_queue_init(circle_queue &que,int n){
    que.elem=new elem_type[n+1];
    if(!que.elem) error_message("内存分配失败");
    que.size=n;
    que.front=que.rear=0;
}

int circle_queue_length(circle_queue que){
    return (que.size-(que.front-que.rear))%que.size;
}

void circle_queue_push(circle_queue &que,elem_type e){
    if((que.rear+1)%que.size==que.front) circle_queue_increment(que);
    que.elem[que.rear]=e;
    que.rear=(que.rear+1)%que.size;
}

bool circle_queue_pop(circle_queue &que,elem_type &e){
    if(que.front==que.rear) return false;
    e=que.elem[que.front];
    que.front=(que.front+1)%que.size;
    return true;
}

void circle_queue_traverse(circle_queue que){
    for(int i=0;(que.front+i)%que.size!=que.rear;i++){
        cout<<que.elem[(que.front+i)%que.size]<<" ";
    }
    cout<<endl;
}

bool circle_queue_empty(circle_queue que){
    return que.front==que.rear;
}

void circle_queue_get_front(circle_queue que,elem_type &e){
    e=que.elem[que.front];
}

//打印杨辉三角,1 1这一行记为第一行
//具体参考严蔚敏《数据结构及应用算法教程》
void yanghui(int n){
    circle_queue que;
    for(int i=1;i<=n;i++) cout<<' ';
    cout<<1<<endl;
    circle_queue_init(que,n+2);
    circle_queue_push(que,0);
    circle_queue_push(que,1);circle_queue_push(que,1);
    int k=1;
    elem_type e,s;
    while(k<n){
        for(int i=1;i<=n-k;i++) cout<<' ';
        circle_queue_push(que,0);
        do{
            circle_queue_pop(que,s);
            circle_queue_get_front(que,e);
            if(e) cout<<e<<' ';
            else cout<<endl;
            circle_queue_push(que,s+e);
        }while(e!=0);
        k++;
    }
    circle_queue_pop(que,e);
    while(!circle_queue_empty(que)){
        circle_queue_pop(que,e);
        cout<<e<<' ';
    }
    cout<<endl;
}

//子集划分
//具体参考严蔚敏《数据结构及应用算法教程》
int division(int r[9][9],int n,int result[]){
    int pre=n,group=0;
    circle_queue que;
    circle_queue_init(que,n);
    for(int i=0;i<n;i++) circle_queue_push(que,i);
    int e;
    int clash[10];
    while(!circle_queue_empty(que)){
        circle_queue_pop(que,e);
        if(e<=pre){
            group++;
            for(int j=0;j<n;j++) clash[j]=0;
        }
        if(clash[e]==0){
            result[e]=group;
            for(int j=0;j<n;j++) clash[j]+=r[e][j];
        }
        else circle_queue_push(que,e);
        pre=e;
    }
    return group;
}

int main()
{
    circle_queue cq;
    circle_queue_init(cq,SIZE);
    cout<<"circular queue: ";
    for(int i=1;i<=6;i++){
        circle_queue_push(cq,i);
    }
    circle_queue_traverse(cq);
    while(cq.front!=cq.rear){
        elem_type e;
        circle_queue_pop(cq,e);
        cout<<e<<"出队后,circular queue: ";circle_queue_traverse(cq);
    }

    cout<<endl;
    cout<<"打印杨辉三角:"<<endl;
    yanghui(4);

    cout<<endl;
    //注意下面的数组一定是9*9的
    int r[9][9]={
                    0,1,0,0,0,1,0,0,0,
                    1,0,0,0,1,1,0,1,1,
                    0,0,0,0,0,1,1,0,0,
                    0,0,0,0,1,0,0,0,1,
                    0,1,0,1,0,0,1,0,1,
                    1,1,1,0,0,0,1,0,0,
                    0,0,1,0,1,1,0,0,0,
                    0,1,0,0,0,0,0,0,0,
                    0,1,0,1,1,0,0,0,0                   
                };
    int result[10];
    int group_num=division(r,9,result); 
    cout<<"划分无冲突子集:"<<endl;
    for(int i=1;i<=group_num;i++){
        cout<<"group"<<i<<": ";
        for(int j=0;j<9;j++){
            if(result[j]==i) cout<<j<<" ";
        }
        cout<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值