数据结构部分代码展示(学习用)

基础顺序结构(顺序表和链表)

顺序表(sqlist)

结构定义

typedef struct {
    ElemType *data;
    int length;
}sqlist;

头文件定义

#include<iostream>
using namespace std;
#define MAXSIZE 100
typedef int ElemType;

函数定义

bool initlist(sqlist &L)//创建顺序表
{
    bool judge=true;
    L.data=new ElemType[MAXSIZE];//为L.dada申请长为MAXSIZE的空间
    if(L.data==NULL)//判断是否申请成功
    {
        cout<<"没有申请到空间"<<endl;
        judge=false;//如果没有申请成功,就将judge改为false
        return judge;//返回false
    }
    return judge;
}
void input(sqlist &L,int n)
{
    if(n<0||n>MAXSIZE)//进行n的合法性判断,如果N小于0或者超过最大数组长度,输出提醒语句
    {
        cout<<"想要输入的数据个数不对"<<endl;
    }
    for(int i=0;i<n;i++)//利用for循环,循环n次输入data的数值
    {
        cin>>L.data[i];
    }
    L.length=n;//将sqlist的长度设置为n
    cout<<"L.length:"<<L.length<<endl;
}
void showlist(sqlist &L)
{
    int i;
    for(i=0;i<L.length;i++)//利用length属性,设计for循环遍历数组的每一个值
    {
        cout<<L.data[i]<<" ";
    }
    cout<<endl;
    cout<<"L.length:"<<L.length<<endl;
}
void deletelist(sqlist &L,int i)
{
    if(i>L.length||i<0)//进行数据的合法性检查,如果i大于顺序表的长度或者
        //i小于0,输出提醒语句
    {
        cout<<"找不到这样的第i位哦"<<endl;
    }
    int j;//设置j找到i的前一位
    for(j=i-1;j<L.length;j++)
    {
        L.data[j]=L.data[j+1];//将j后一位的数值赋给j,原i位被覆盖
    }
    L.length-=1;//顺序表的长度减一
}
void insertlist(sqlist &L,int j,int e)
{

    if(j<0||j>MAXSIZE)//进行数据的合法性检查,如果i大于顺序表的长度或者
        //i小于0,输出提醒语句
    {
        cout<<"插入的位置不对"<<endl;
    }
    L.length++;//因为要插入一位数,所以提前把顺序表的长度增加一位
    int x;
    for(x=L.length-1;x>j;x--)//从数组的最后一位开始循环,
        //在插入位置i的前一位停止
    {
        L.data[x]=L.data[x-1];//将x前一位的数据赋值给x的后一位
    }
    L.data[j]=e;//将的i位的数据置为e;
}
void cleanlist(sqlist &L)
{
    L.length=0;//直接将顺序表的长度置为0
}
void destrylist(sqlist &L)
{
    delete []L.data;//删除数组空间
    L.length=0;//将顺序表的长度置为0
}
void showlength(sqlist L)
{
    cout<<"顺序表的长度:"<<L.length<<endl;
}
void serlist(sqlist &L)//逆置顺序表
{
    ElemType *q,*p;//设置两个Elemtype类型的指针,以从开始和末尾移动数组元素
    ElemType temp;//作为临时变量保存q的数值
    q=&L.data[0];//将q指向数组的开头
    p=&L.data[L.length-1];//将p指向数组的末尾
    while(q<p)//令数组从开头和结尾依次向前前进一位和从后向前一位
    {
        temp=*q;//让temp先保存原q的值,
        *q=*p;//将q的值置为后面的p的值
        *p=temp;//q的值赋值为temp保存的原来q的值
        q++;//q从原来数组的位置前进一位
        p--;//p从原来数组的位置从后向前前进一位
    }
}
void deletex (sqlist &L,int x)
{
    int i,j;
    for(i=0;i<L.length;i++)//遍历完整个数组
    {
        if(L.data[i]==x)//当发现有数组中有与x相同的元素时
        {//将这个位置的数组元素用后一位的元素覆盖
            for(j=i;j<L.length;j++)
            {
                L.data[j]=L.data[j+1];
            }
            L.length--;//将顺序表的长度减一
            i--;//这里是为了将i重新置为相对的开始状态
        }
    }
}

main函数定义

#include"sqlisthead.h"
#include"sqlistdef.h"
#include"sqlistcpp.h"
int main()
{
    int inputbot,insetdata,insetloate,n,i,j,e,x;
    sqlist L;
    do{
    cout<<endl;
    cout<<"\t按0开始初始化顺序表"<<endl;
    cout<<"\t按1开始输入n位顺序表数据"<<endl;
    cout<<"\t按2开始查看顺序表数据"<<endl;
    cout<<"\t按3开始删除指定的i位的数据"<<endl;
    cout<<"\t按4开始向插入第i位后插入数据e"<<endl;
    cout<<"\t按5开始清除线性表"<<endl;
    cout<<"\t按6开始销毁线性表"<<endl;
    cout<<"\t按7开始取得顺序表的长度"<<endl;
    cout<<"\t按8将顺序表逆转"<<endl;
    cout<<"\t按9删除顺序表中的所有X元素"<<endl;
    cout<<"\t按-1退出操作"<<endl;
    cin>>inputbot;
        if(inputbot==0)
        {
            initlist(L);
            cout<<L.data;
        }
        else if(inputbot==1)
        {
            cout<<"请输入顺序表的个数"<<endl;
            cin>>n;
            input(L,n);
        }
        else if(inputbot==2)
        {
            showlist(L);
        }
        else if(inputbot==3)
        {
            cin>>i;
            deletelist(L,i);
        }
        else if(inputbot==4)
        {
            cin>>j;
            cin>>e;
            insertlist(L,j,e);
        }
        else if(inputbot==5)
        {
            cleanlist(L);
        }
        else if(inputbot==6)
        {
            destrylist(L);
        }
        else if(inputbot==7)
        {
            showlength(L);
        }
       else if(inputbot==8)
       {
           serlist(L);
       }
       else if(inputbot==9)
       {
           cout<<"请输入想要删除的元素X数值"<<endl;
           cin>>x;
           deletex(L,x);
       }
    }while(inputbot!=-1);
}


PS:main函数的条件判断用switch…case…结构更好,效率更高
运行截图:
在这里插入图片描述

带头结点的单链表

头文件定义

#include<iostream>
using namespace std;
typedef int Elemtype;

结构体定义

typedef struct LNode{
    Elemtype data;
    struct LNode *next;
}LNode;
typedef LNode* linklist;

函数体定义:

void initlist(linklist L)
{
    L=new LNode;//新建一个节点空间
    if(L==NULL)
    {
        cout<<"分配内存失败"<<endl;//提示性语句
    }
    L->next=NULL;//将节点的next置为NULL
}
void showlinklist(linklist L)
{
    cout<<"L=>";
    LNode* p=L;//将P和L的头节点链接
    while(p->next!=NULL)//当p未到链表结尾处时一直循环
    {
        p=p->next;//p走向下一个节点
        cout<<p->data<<"=>";
    }
    cout<<"NULL"<<endl;
}
void insertlist(linklist &L,int i,Elemtype e)
{
    int count=0;
    LNode* p=L;
    while(p->next!=NULL&&count<i-1)//向下循环直至到达i节点的前一个节点
    {
        p=p->next;
        count++;
    }
    if(!p||(count>i-1))//合法性判断,当i>链表的长度或者i<0时,输出提示语句
    {
        cout<<"想插入的位置i不合法"<<endl;
    }
    LNode* s;
    s=new LNode;//申请一个新的空间
    s->data=e;//赋值
    s->next=p->next;//将原来p链接的节点转而链接到s后面
    p->next=s;//将节点s链接到p的后面
}
void deletelist(linklist &L,int x)
{
    LNode* p=L;
    int j=0;
    while((p->next)&&(j<x-1))//当p不为结尾NULL并且没有到达x节点时
        //p不断后移,j++
    {
        p=p->next;
        j++;
    }
    if(p==NULL||(j>x-1))//合法性检查
    {
        cout<<"想删除的位置x不合法"<<endl;
    }
    LNode* q=p->next;//设置q保存p后面链接的地址
    p->next=q->next;//让p指向原来p的后两位
    delete q;//释放q,即删除原来的节点p
}
void getelem(linklist L,int i)
{
    Elemtype e;
    linklist p=L->next;//将p指向第一个节点
    int j=1;
    while(p&&j<i)//遍历链表,直至p找到i的位置
    {
        p=p->next;
        j++;
    }
    if(p==NULL||j>i)//合法性检查
    {
        cout<<"想取值的位置y不合法"<<endl;
    }
    e=p->data;//将p的数据域的部分通过e带出
    cout<<"第y个位置的值为"<<e<<endl;
}
void createlist(linklist &L,int n)
{
//通过尾插法创建数组,先创建一个空节点,指针域置为NULL,r指向L
    LNode* r;
    LNode* p;
    L=new LNode;
    L->next=NULL;
    r=L;
    for(int i=0;i<n;i++)
    {
        p=new LNode;//新建一个新节点
        cin>>p->data;
        p->next=NULL;//将p的指针域置为NULL
        r->next=p;//将新节点p插入尾节点r之后
        r=p;//p指向新的尾节点
    }
}
void deleteall(linklist &L)
{
    linklist q;
    while(L)//当链表没有循环到末尾时
    {
        q=L->next;//q承载L的后继指针
        delete(L);//清空L
        L=q;//L重新指向q承载的指针
    }
}
int showlength(linklist L)
{
    int countx=0;
    linklist p;
    p=L->next;
    while(p)
    {
        countx++;
        p=p->next;
    }
    return countx;
}
void findmaxmin(linklist L,int flag)
{
    linklist p;
    Elemtype temp;
    p=L;
    p=p->next;
    temp=p->data;
    if(flag==1)
    {
    while(p)
    {
        if((p->data)>temp)
        {
            temp=p->data;
        }
        p=p->next;
    }
    cout<<"最大数是"<<temp<<endl;
    }
    else {
        while(p)
        {
            if(p->data<temp)
            {
                temp=p->data;
            }
            p=p->next;
        }
        cout<<"最小数是"<<temp<<endl;
    }
}
void reverselist(linklist &head)
{
    linklist p,q;
    p=head->next;
    head->next=NULL;//首先我们让链表为空,断开(head->next=NULL),
    //在这时我们只需要将p和q分别用头插法的方式链接起来,链表的逆序也就完成了。
        while(p!=NULL)
        {
            q=p;
            p=p->next;//p向后遍历
            q->next=head->next;//利用头插法
            head->next=q;//将q连接到head后面
        }
}

main函数定义

int main()
{
    linklist L;
    int n,y,x,i,flag;
    Elemtype e;
    int input;
    cout<<"\t按1初始化链表"<<endl;
    cout<<"\t按2向链表输入N个数据"<<endl;
    cout<<"\t按3向第i个位置插入数据e"<<endl;
    cout<<"\t按4删除第x位置的数据"<<endl;
    cout<<"\t按5显示链表的y个位置的数据大小"<<endl;
    cout<<"\t按6展示链表"<<endl;
    cout<<"\t按7销毁链表"<<endl;
    cout<<"\t按8求得链表的长度"<<endl;
    cout<<"\t按9查询链表中的最大最小值"<<endl;
    cout<<"\t按10进行链表的逆置"<<endl;
    cin>>input;
    do{
        if(input==1)
        {
            initlist(L);
        }
        else if(input==2)
        {
            cout<<"确认的数据的个数"<<endl;
            cin>>n;
            createlist(L,n);
        }
         else if(input==3)
         {
             cout<<"请输入i"<<endl;
             cin>>i;
             cout<<"请输入e"<<endl;
             cin>>e;
             insertlist(L,i,e);
         }
         else if(input==4)
         {
             cout<<"请输入x"<<endl;
             deletelist(L,x);
         }
         else if(input==5)
         {
             cout<<"请输入y"<<endl;
             cin>>y;
             getelem(L,y);
         }
         else if(input==6)
         {
             showlinklist(L);
         }
         else if(input==7)
         {
             deleteall(L);
         }
         else if(input==8)
         {
           int length= showlength(L);
           cout<<"链表的长度为"<<length<<endl;
         }
         else if(input==9)
         {
             cout<<"请输入想要找到是最大数还是最小数"<<endl;
             cout<<"找最大数输入1,找最小数输入2"<<endl;
             cin>>flag;
             findmaxmin(L,flag);
         }
         else if(input==10)
         {
            reverselist(L);
         }
         cout<<"\t按1初始化链表"<<endl;
    cout<<"\t按2向链表输入N个数据"<<endl;
    cout<<"\t按3向第i个位置插入数据e"<<endl;
    cout<<"\t按4删除第x位置的数据"<<endl;
    cout<<"\t按5显示链表的y个位置的数据大小"<<endl;
    cout<<"\t按6展示链表"<<endl;
    cout<<"\t按7销毁链表"<<endl;
    cout<<"\t按8求得链表的长度"<<endl;
    cout<<"\t按9查询链表中的最大最小值"<<endl;
    cout<<"\t按10进行链表的逆置"<<endl;
    cout<<"\t按-1退出操作"<<endl;
        cin>>input;
    }while(input!=-1);

}

运行截图:
在这里插入图片描述

顺序栈

头文件定义

#include<iostream>
#define maxsize 100
using namespace std;
typedef int Selemtype;

结构定义

typedef struct {//顺序栈的结构体定义
    Selemtype *base;//栈的尾指针
    Selemtype *top;//栈的头指针,除初始化以外,栈顶指针始终位于栈顶元素的上一位
    int stacksize;//栈的长度
}sqstack;

函数定义

void initstack(sqstack &s)
//顺序的初始化

{
    s.base=new Selemtype[maxsize];//分配一块大小为maxsize的连续空间
    if(!s.base)//如果分配失败就输出提示性语句
    {
        cout<<"未能分配空间"<<endl;
    }
    else{//分配成功则:
    s.top=s.base;//将top和base指向同一个空间
    s.stacksize=maxsize;//将栈的长度初始化
    }
}
int  lookstack(sqstack s){
//查看栈的长度
   int length;
   length=s.top-s.base;//因为数组空间是连续的,所以长度为top-base
   return length;
}//返回栈顶长度
void push (sqstack &s,Selemtype e)
//入栈操作
{
    if(s.top-s.base==s.stacksize)//如果数组空间的长度已经等于分配的最大长度
    {
        cout<<"数组空间已满"<<endl;//输出提示语句
    }
    else{//如果数组空间为满,则
    *(s.top)=e;//元素e压入栈顶,栈顶指针加一
    s.top++;
    }
}
void pop(sqstack &s)
//弹栈操作
{
    Selemtype e;
    if(s.top==s.base)//进行判空操作
    {
    cout<<"顺序栈为空"<<endl;
    }
    else{
    s.top--;//栈顶指针减一
    e=*s.top;//将栈顶元素赋给e
    cout<<"出栈元素为"<<e<<endl;
    }
}
void gettop(sqstack s)
{
//取得栈顶元素
    if(s.top==s.base)//如果栈为空,输出提示语句
    {
        cout<<"栈为空"<<endl;
    }
    else{//栈非空,用e带出栈顶元素的值
    int e=*(s.top-1);
    cout<<"栈顶元素为"<<e<<endl;
    }
}
bool judge(sqstack S)
{//判断是否为空栈
    if(S.base==S.top)
    {//如果栈头栈尾指向同一个地址,说明为空栈
        return false;
    }
    else{
        return true;
    }
}
void changlle(int n,int r)
{//将n进制数转换为r进制数
    sqstack s;
    initstack(s);//创建一个栈来保存转换结果
    while(n)//利用除法取余
    {
        push(s,n%r);//将余数入栈
        n=n/r;
    }
    while(judge(s))//当未到栈底一直执行弹栈操作
    {
        pop(s);
    }
}
void clearstack(sqstack &s)
{//清空栈
    s.top=s.base;
}
void destroy(sqstack &s)
{//销毁栈空间
    delete[] s.base;
    s.base=NULL;
    s.top=NULL;
    s.stacksize=0;
}

mian函数定义:

int main()
{
    sqstack s;
    int input,e,n,i,r;
    cout<<"\t 按1开始初始化顺序栈"<<endl;
    cout<<"\t 按2求顺序表长"<<endl;
    cout<<"\t 按3将元素e入栈"<<endl;
    cout<<"\t 按4将元素i出栈"<<endl;
    cout<<"\t 按5取得栈顶元素"<<endl;
    cout<<"\t 按7将十进制数n转变为r进制数"<<endl;
    cout<<"\t 按8开始清空顺序栈"<<endl;
    cout<<"\t 按9开始销毁顺序栈"<<endl;
    cin>>input;
    do{
       switch(input)
       {
        case(1):
        {
         initstack(s);
         break;
        }
        case(2):
        {
            cout<<"顺序栈长度为:";
            int length=lookstack(s);
            cout<<length<<endl;;
            break;
        }
        case(3):
        {
           cout<<"入栈元素e为:"<<endl;
            cin>>e;
            push(s,e);
            break;
        }
        case(4):
        {
            pop(s);
            break;
        }
        case(5):
        {
        gettop(s);
        break;
        }
        case(6):
            {
                bool tell=judge(s);
                if(tell)
                {
                    cout<<"不为空表"<<endl;
                }
                else{
                    cout<<"为空表"<<endl;
                }
                break;
            }
            case(7):
            {
                cout<<"请输入需转换的十进制数n"<<endl;
                cin>>n;
                cout<<"请输入想要转换的进制r:"<<endl;
                cin>>r;
                changlle(n,r);
            }
            case(8):
                {
                    clearstack(s);
                }
            case(9):
                {
                    destroy(s);
                }
       }
    cout<<"\t 按1开始初始化顺序栈"<<endl;
    cout<<"\t 按2开始输出栈长"<<endl;
    cout<<"\t 按3将元素e入栈"<<endl;
    cout<<"\t 按4将元素i出栈"<<endl;
    cout<<"\t 按5取得栈顶元素"<<endl;
    cout<<"\t 按6判断是否为空栈"<<endl;
    cout<<"\t 按7将十进制数n转变为r进制数"<<endl;
    cout<<"\t 按8开始清空顺序栈"<<endl;
    cout<<"\t 按9开始销毁顺序栈"<<endl;
    cin>>input;
    }while(input!=-1);
}

运行截图:
在这里插入图片描述

链栈

头文件定义

#include<iostream>
using namespace std;
typedef int elemtype;

结构体定义

typedef struct Stacknode{//定义节点结构体
    elemtype  data;
    struct Stacknode *next;
}Stacknode;

函数定义:

void initstack(linkstack &s)
//初始化链栈,构建一个空栈,不必设置头指针
{
    s=NULL;
}
void push(linkstack &s,elemtype e)
//将元素e入栈
{
    linkstack p;
    p=new Stacknode;//生成新节点
    p->data=e;//为节点的数据域赋值
    p->next=s;//将新节点链接到链尾
    s=p;//将s指向链尾
}
elemtype lengthstack(linkstack s)
//求链栈的长度
{
    elemtype length=0;//初始化长度
    while(s)//从链表的开头依次向后遍历,未到达表尾NULL就一直向后
    {
        length++;
        s->next=s;//修改节点的指针域,使得指向下一个节点
    }
    return length;//返回链栈的长度
}
void pop(linkstack &s,elemtype &e)
//进行弹栈操作,通过e将弹出元素数值带出
{
    linkstack p;//设置一个指针来方便后面的指针修改和删除
    if(s==NULL)
    //先判断链栈是否为空
    {
        cout<<"栈为空"<<endl;
    }
    else{
    e=s->data;//得到栈顶的元素值
    p=s;//用p临时保存栈顶元素空间,以备释放
    s=s->next;//将原来的栈顶指针指向下一个指针
    delete p;//释放原栈顶元素空间
    }
}
elemtype gettop(linkstack s)
//取得栈顶元素
{
    if(s!=NULL)//进行链栈的判空
    {
        return s->data;//不为空,则返回栈顶元素值
    }
    else{
        return -1;//为空则返回-1
    }
}
bool judge(linkstack s)
//判断栈是否为空
{
    if(s==NULL)
    {//如果栈为空,返回false
        return false;
    }
    else{
        //如果不空,返回true
        return true;
    }
}
elemtype getlength(linkstack s)
//取得链栈的长度
{
    elemtype length=0;
    while(s)//当链表未到达队尾时,一直向后循环+1
    {
        length++;
        s=s->next;//指针向后移动
    }
    return length;
}
void deletestack(linkstack &s)
//销毁链栈
{
    linkstack p;//设置一个指针来方便后面的指针修改和删除
    while(s)
    {
        p=s->next;//用p临时保存栈顶元素空间,以备释放
        s=s->next;//s向后遍历,直至到达队尾
        delete(p);//释放p元素的空间
    }
}

main函数定义:

int main(){
    int input;
    linkstack s;
    elemtype e=0,n,length,top;
    bool flag;
    cout<<"\t 按1开始初始化链栈"<<endl;
    cout<<"\t 按2开始将元素n入栈"<<endl;
    cout<<"\t 按3开始元素e出栈"<<endl;
    cout<<"\t 按4取得栈顶元素"<<endl;
    cout<<"\t 按5判断是否为空表"<<endl;
    cout<<"\t 按6输出栈长"<<endl;
    cout<<"\t 按7销毁栈"<<endl;
    cin>>input;
    do{
        switch(input)
        {
        case(1):
            {
                initstack(s);
                break;
            }
        case(2):
         {
            cout<<"请输入想要输入的元素n"<<endl;
            cin>>n;
            push(s,n);
            break;
         }
        case(3):
            {
                pop(s,e);
                cout<<"出栈元素e为"<<e<<endl;
                break;
            }
        case(4):
            {
                top=gettop(s);
                if(top!=-1){
                cout<<"栈顶元素为:"<<top<<endl;
                }
                else{
                    cout<<"栈为空,无元素"<<endl;
                }
                break;
            }
        case(5):
            {
            if(judge(s))
            {
                cout<<"不为空表"<<endl;
            }
            else{
                cout<<"为空表"<<endl;
            }
            break;
            }
        case(6):
            {
                length=getlength(s);
                cout<<"链栈长为"<<length<<endl;
                break;
            }
        case(7):
            {
                deletestack(s);
                break;
            }
        }
    cout<<"\t 按1开始初始化链栈"<<endl;
    cout<<"\t 按2开始将元素n入栈"<<endl;
    cout<<"\t 按3开始元素e出栈"<<endl;
    cout<<"\t 按4取得栈顶元素"<<endl;
    cout<<"\t 按5判断是否为空表"<<endl;
    cout<<"\t 按6输出栈长"<<endl;
    cout<<"\t 按7销毁栈"<<endl;
    cin>>input;
    }while(input!=-1);
}

运行截图:

在这里插入图片描述

队列

循环队列

头文件定义

#include<iostream>
#define maxsize 100
using namespace std;
typedef int qelemtype;

结构体定义

//如果设有循环队列,必须为设定一个最大队列长度,如果用户无法预估队列的最大元素,应该用链队
typedef struct{//循环队列的定义
    qelemtype *base;//储存空间的基地址
    int front;//头指针
    int rear;//尾指针
}sqqueue;

函数定义

bool initsqqueue(sqqueue &s)
{
    s.base=new qelemtype[maxsize];//为队列分配一个最大容量为maxsize的空间
    if(s.base==NULL)
    {
        return false;
    }
    else
    {//头指针和尾指针置零,队列为空
     s.front=0;
     s.rear=0;
    return true;
    }
}
int getlength(sqqueue s)
{
    int length;
    //返回元素的个数,即队列的长度
    length=(s.rear-s.front+maxsize)%maxsize;
    return length;
}
bool enqueue(sqqueue &s,qelemtype e)
{
    if((s.rear+1)%maxsize==s.front)//尾指针在循环意义上加一后等于头指针,
        //表明队满
    {
        return false;
    }
    else{
    s.base[s.rear]=e;//新元素插入队尾
    s.rear=(s.rear+1)%maxsize;//队尾指针加一
    return true;
    }
}
bool dequeue(sqqueue &s,qelemtype &i)
{
    if(s.front==s.rear)//队为空
    {
        return false;
    }
    else{
    i=s.base[s.front];//保存队头元素
    s.front=(s.front+1)%maxsize;//队头指针加1
    return true;
    }
}
int gettop(sqqueue s)
{
    if(s.front!=s.rear)//队列不为空
    {
        return s.base[s.front];//返回队头元素的值,队头指针不变
    }
    else{
        return -1;
    }
}
void clearsqqueue(sqqueue &s)
{
    s.front=0;
    s.rear=0;
}
void destroy(sqqueue &s)
{
    delete[] s.base;//清空数组空间
    s.front=0;
    s.rear=0;
}
void lookall(sqqueue s)
{
    if(s.front==s.rear){
        cout<<"循环队列为空"<<endl;
    }
    else{
        while(s.front!=s.rear)
        {
            cout<<s.base[s.front]<<" ";
            s.front=(s.front+1)%maxsize;
        }
        cout<<endl;
    }
}

main函数定义

int main()
{
   int input;
   int e,i,length,top;
   sqqueue s;
   bool flag1,flag2,flag3;
   cout<<"\t 按1开始初始化循环队列"<<endl;
   cout<<"\t 按2开始求队列长度"<<endl;
   cout<<"\t 按3开始将元素e入队尾"<<endl;
   cout<<"\t 按4开始将队头元素i出列"<<endl;
   cout<<"\t 按5开始取得队头元素"<<endl;
   cout<<"\t 按6开始清空队列"<<endl;
   cout<<"\t 按7开始销毁队列"<<endl;
   cout<<"\t 按8开始输出循环队列全部元素"<<endl;
   cout<<"\t 按-1开始退出程序"<<endl;
   cin>>input;
   do{
   switch(input)
   {
   case(1):
    {
        flag1=initsqqueue(s);
        if(flag1)
        {
            cout<<"循环队列初始化成功"<<endl;
        }
        else{
            cout<<"循环队列建立失败"<<endl;
        }
        break;
    }
   case(2):
    {
        length=getlength(s);
        cout<<"循环队列的长度为"<<length<<endl;
        break;
    }
    case(3):
    {
        cout<<"请输入想要加入队尾的元素e"<<endl;
        cin>>e;
        flag2=enqueue(s,e);
        if(flag2)
        {
            cout<<"元素e成功加入队尾"<<endl;
        }
        else{
            cout<<"队列已经装满,无法加入"<<endl;
        }
        break;
    }
    case(4):
    {
        flag3=dequeue(s,i);
        if(flag3)
        {
            cout<<"队头元素"<<i<<"已经出队"<<endl;
        }
        else
        {
            cout<<"队列为空,无法弹出元素"<<endl;
        }
        break;
    }
    case(5):
    {
       top=gettop(s);
       if(top!=-1)
       cout<<"队列头元素为"<<top<<endl;
       else{
        cout<<"队列为空"<<endl;
       }
       break;
    }
    case(6):
    {
        clearsqqueue(s);
        break;
    }
    case(7):
    {
        destroy(s);
        break;
    }
    case(8):
        {
            lookall(s);
            break;
        }
   }
   cout<<"\t 按1开始初始化循环队列"<<endl;
   cout<<"\t 按2开始求队列长度"<<endl;
   cout<<"\t 按3开始将元素e入队尾"<<endl;
   cout<<"\t 按4开始将队头元素i出列"<<endl;
   cout<<"\t 按5开始取得队头元素"<<endl;
   cout<<"\t 按6开始清空队列"<<endl;
   cout<<"\t 按7开始销毁队列"<<endl;
   cout<<"\t 按8开始输出循环队列全部元素"<<endl;
   cout<<"\t 按-1开始退出程序"<<endl;
   cin>>input;
   }while(input!=-1);
   return 0;
}

运行截图:
在这里插入图片描述
链队列:
头文件定义:

#include<iostream>
using namespace std;
typedef int qelemtype;

结构体定义:

typedef struct qnode{
    qelemtype data;
    struct qnode *next;
}qnode;
typedef qnode* queueptr;
typedef struct{
    queueptr front; //队头指针
    queueptr rear;  //队尾指针
}linkqueue;

函数定义:

void initqueue(linkqueue &s)
{//构建一个空队列s
    s.front=s.rear=new qnode;//生成新节点作为头节点,linkqueue的队头和队尾指向此节点
    s.front->next=NULL;//头节点的指针域置为空
}
int getlength(linkqueue s)
{//返回队列元素的个数
    int length=0;
    queueptr p;//生成一个节点类指针,方便进行链表遍历
    if(s.front==s.rear)//判断是否为空表
    {
        return 0;
    }
    p=s.front->next;//p指向首元节点
    while(p)
    {
        length++;
        p=p->next;//向后移动,直至到达队尾
    }
    return length;
}
bool enqueue(linkqueue &s,qelemtype e)
{//将元素e插入成为新的队尾元素
    queueptr p;//生成一个节点类指针,方便对节点的数据和指针进行操作
    p=new qnode;
    if(p==NULL)//如果空间申请失败,返回false
    {
        return false;
    }
    p->data=e;//将节点p的数据置为e
    p->next=NULL;//p的指针域置为NULL
    s.rear->next=p;//s的尾部置为p
    s.rear=p;//将怕置为新的尾部
    return true;
}
bool dequeue(linkqueue &s,qelemtype &i)
{//删除s的队头元素,用i返回其值
    if(s.front==s.rear)//若队列为空,返回false
    {
        return false;
    }
    queueptr p;//生成一个节点类指针,方便对节点的数据和指针进行操作
    p=s.front->next;//p指向首元节点
    i=p->data;//i保存队头元素
    s.front->next=p->next;//将首元节点的指针修改为原首元节点的后一位
    if(s.rear==p)//针对只有一个元素的特殊情况,首元节点和尾节点为同一个
    {
        s.rear=s.front;//最后一个元素被删,队尾指针指向头指针
    }
    delete p;//释放原队头元素空间
    return true;
}
qelemtype gettop(linkqueue s)
{//返回s的队头元素,不修改指针
    if(s.front!=s.rear)
    {//返回队头元素的值,队头指针不变
        return s.front->next->data;
    }
    else{//为空队
        return -1;
    }
}
void clearall(linkqueue &s)
{//清空队列
    s.front=s.rear;
}
void destroy(linkqueue &s)
{//销毁队列空间
    while(s.front)//当队列未到达队尾
    {
        s.rear=s.front->next;//s的尾部保存s的头部的下一位的指针
        delete(s.front);//释放原s的头部空间
        s.front=s.rear;//将新s的头部置为保存的s的尾部指针,以便向后遍历
    }
}
void print(linkqueue s)
{//打印队列的数据元素
    if(s.front==s.rear)//队列为空
    {
        cout<<"队列为空"<<endl;
    }
    queueptr ptr=s.front->next;//使ptr指向首元节点
    while(ptr!=s.rear)
    {
        cout<<ptr->data<<" ";
        ptr=ptr->next;//ptr向下遍历
    }
    cout<<ptr->data<<endl;
}
bool judge(linkqueue s)
{//判断是否为空表
    if(s.front==s.rear)
    {
        return true;
    }
    return false;
}

main函数定义:

int main()
{
    int input;
    linkqueue s;
    qelemtype e,i,x;
    int length;
    bool flag1,flag2,flag3;
    cout<<"\t 按1开始初始化链队"<<endl;
    cout<<"\t 按2开始求链队长度"<<endl;
    cout<<"\t 按3开始将元素e插入队尾"<<endl;
    cout<<"\t 按4开始链队头元素i出队"<<endl;
    cout<<"\t 按5取得队头元素x"<<endl;
    cout<<"\t 按6开始清空链队"<<endl;
    cout<<"\t 按7开始销毁链队"<<endl;
    cout<<"\t 按8判断链队是否为空"<<endl;
    cout<<"\t 按9开始打印队列元素"<<endl;
    cout<<"\t 按-1退出操作"<<endl;
    cin>>input;
    do{
        switch(input)
        {
        case(1):
            {
                initqueue(s);
                break;
            }
        case(2):
            {
                length=getlength(s);
                cout<<"链表的长度为"<<length<<endl;
                break;
            }
        case(3):
            {
                cout<<"请输入想要插入的元素e"<<endl;
                cin>>e;
                flag1= enqueue(s,e);
                if(flag1)
                {
                    cout<<"元素e插入成功"<<endl;
                }
                else{
                    cout<<"元素插入失败"<<endl;
                }
                break;
            }
        case(4):
            {
                flag2=dequeue(s,i);
                if(flag2)
                {
                    cout<<"元素i:"<<i<<"已出队"<<endl;
                }
                else{
                    cout<<"队列为空,无元素可以出队"<<endl;
                }
                break;
            }
        case(5):
            {
                x=gettop(s);
                if(x!=-1)
                {
                cout<<"队头元素为"<<x<<endl;
                }
                else{
                    cout<<"队列为空"<<endl;
                }
                break;
            }
        case(6):
            {
                clearall(s);
                break;
            }
        case(7):
            {
                destroy(s);
                break;
            }
        case(8):
            {
                flag3=judge(s);
                if(flag3)
                {
                    cout<<"为空队列"<<endl;
                }
                else{
                    cout<<"不为空队列"<<endl;
                }
                break;
            }
        case(9):
            {
                print(s);
                break;
            }
        }
    cout<<"\t 按1开始初始化链队"<<endl;
    cout<<"\t 按2开始求链队长度"<<endl;
    cout<<"\t 按3开始将元素e插入队尾"<<endl;
    cout<<"\t 按4开始链队头元素i出队"<<endl;
    cout<<"\t 按5取得队头元素x"<<endl;
    cout<<"\t 按6开始清空链队"<<endl;
    cout<<"\t 按7开始销毁链队"<<endl;
    cout<<"\t 按8判断链队是否为空"<<endl;
    cout<<"\t 按9开始打印队列元素"<<endl;
    cout<<"\t 按-1退出操作"<<endl;
    cin>>input;
    }while(input!=-1);
}

运行截图:

在这里插入图片描述

递归汉诺塔

#include<iostream>
using namespace std;
 int m=0;
void move(char A,int n,char C){
    cout<<"总移动的次数"<<++m<<endl;
    cout<<"移动过程次数"<<n<<","<<A<<","<<C<<endl;
}
void Hanio(int n,char A,char B,char C){
    if(n==1)
    {
        move(A,1,C);
    }
    else{
        Hanio(n-1,A,C,B);
        move(A,n,C);
        Hanio(n-1,B,A,C);
    }
}
int main(){
    int n;
    cout<<"需要移动的圆盘总个数:"<<endl;
    cin>>n;
    char A,B,C;
    cout<<"请输入三个柱子的名称"<<endl;
    cin>>A;
    cin>>B;
    cin>>C;
    Hanio(n,A,B,C);
}

在这里插入图片描述

字符串

头文件定义:

#include<stdio.h>
#include<iostream>
using namespace std;

结构体定义

#include<stdio.h>
#include<iostream>
using namespace std;

函数定义:

void Inputstring(SString &s,char ch1[]){//将ch1数组的内容输入进字符串s中
        int i=0;
        while(ch1[i]!='\0'){//当ch1未到达末尾,将ch1的内容赋给s
            s.str[i+1]=ch1[i];//将ch1的内容输入s中,s的字符串内容以1作为开始
            i++;
        }
        s.str[i+1]='\0';//将字符串封上'\0',使其符合字符串的特征
        s.length=i;//s的长度为去除'\0'的长度。
}
void Outputstring(SString s){//输出字符串s的内容
    if(s.length!=0){//判断s的内容是否为空,如果非空就输出
        for(int i=1;i<=s.length;i++){//从第一个字符到最后一个字符,依次输出
            cout<<s.str[i]<<" ";
        }
        cout<<endl;
    }
    else{
        cout<<"字符串为空"<<endl;
    }
}
int stringlength(SString s){//返回字符串s的长度
    return s.length;
}

int StrCompare(SString s,SString t){//比较字符串的ASCiLL大小和字符串的长度,如果相等返回0,字符不相等就返回字符的差值
    int i=1,j=1;
    for(i=1,j=1;i<=s.str[i]&&j<=t.length;i++,j++){//循环比较S和T的ASCILL码大写,如果不相等就返回差值
        if(s.str[i]!=t.str[j]){
            return s.str[i]-t.str[i];
        }
    }
    if(s.length!=t.length){
        return s.length-t.length;//比较两个字符串的长度,返回长度差值
    }
    return 0;
}
bool StrCat(SString &s,SString t){//将字符串t黏贴在字符串s后面,操作成功返回true,操作失败返回false
    int s_length,t_length,i;//将两个变量赋值为,S和T的长度,方便后面的操作
    s_length=s.length;
    t_length=t.length;
    if(s_length+t_length>maxsize){//判断黏贴操作是否合法,如果黏贴后的字符串长度长于maxsize,操作非法
            return false;
    }
    else{//从t的第一个字符到t的'\0'都赋给从s原尾部的'\0'到后面的空间
        for(i=1;i<=t_length+1;i++){
            s.str[s.length+1]=t.str[i];
            s.length++;
        }
        s.length--;//减去字符串的'\0'位置
        return true;
    }
}
bool StringCopy(SString &s,SString t){//将字符串s的内容替换为字符串t的内容,成功返回true,失败返回false
        int i,t_length;
        t_length=t.length;
        if(t_length>maxsize){//如果t的长度超过maxsize,操作不合法,返回false
            return false;
        }
        else{//从t的第一个字符到t的'\0'都赋给s的字符串
            for(i=1;i<=t_length+1;i++){
                s.str[i]=t.str[i];
            }
            s.length=t.length;//将s的长度改为t的长度
            return true;
        }
}
bool  SubString(SString s,SString &sub,int  pos,int len){//从S的第pos位置开始截取len位组成新字符串sub,成功返回true,失败返回false
    int i;
    if(pos>s.length||pos<=0||len>s.length||len<=0||len>s.length-pos){//合法性检查,如果pos<=0或者pos超过了s的长度或者len的长度<=0或者len比合法长度长,返回false
        return false;
    }
    else{//从pos位(包括pos)向后截取len位组成新的sub字符串
         for(i=1;i<=len;i++,pos++){//从s的pos位开始为sub赋值
            sub.str[i]=s.str[pos];
         }
         sub.str[len+1]='\0';//将字符串封上'\0',使其符合字符串的特征
        sub.length=len;//sub的长度就是len的长度
        return true;
    }
}

int Index_BF(SString s,SString t,int pos){//从s的第pos位置开始找子串t,返回s中与t完全相同的位置。如果不存在返回0
        int i=pos,j=1;//初始化
        while(i<=s.length&&j<=t.length){//两个串均为比较到串尾
            if(s.str[i]==t.str[j]){//继续比较后继字符
                i++;
                j++;
            }
            else{//指针后退重新开始匹配
                i=i-j+2;
                j=1;
            }
        }
        if(j>t.length){
            return i-t.length;//匹配成功
        }
        else{
            return 0;//匹配失败
        }
}
int Index_KMP(SString s,SString t,int pos,int next[]){//l利用next数组来求字符串t的回退距离
    int i=pos,j=1;
    while(i<s.length&&j<=t.length){
        if(j==0||s.str[i]==t.str[j]){
            i++;
            j++;
        }
        else{
            j=next[j];
        }
    }
    if(j>t.length){
        return i-t.length;
    }
    else{
        return 0;
    }
}
void get_next(SString t,int next[]){//求i位的最大前后缀集合长度
    int i=1;
    next[i]=0;//next数组的初值默认为0
    int j=0;
    while(i<t.length){
        if(j==0||t.str[i]==t.str[j]){
            i++;
            j++;
            next[i]=j;
        }
        else{
            j=next[j];
        }
    }
}
void StrCount(SString s){//统计字符串中的A~Z个数
    int *zmcount;//用于承载字符统计结果
          int res,sum=0;
    zmcount=new int[maxsize];
    int i,j,k=0;
    zmcount[maxsize]={0};//为数组赋初值,防止数据有误
        for(j=65,k=0;j<=90&&k<maxsize;j++,k++){//从A字符开始和字符串中的内容比较
                zmcount[k]=0;//统计结果初始化
         for(i=1;i<=s.length;i++){//从字符串的开头开始比较
            if((int)s.str[i]==j){
                zmcount[k]+=1;//发现于字符相同的就加一
            }
         }
        }
        //展示zmcount数组内容
        for(i=0;i<26;i++){
                res=zmcount[i];
                sum+=res;
            cout<<(char)(i+65)<<"的个数为:"<<res<<endl;//强制字符串转换
        }
        cout<<"总大写字母统计个数"<<sum<<endl;
}
bool CheckStr(SString S){//判断S中所给的栈的操作序列是否合法(栈的初态和终态均为空,'I'和'O'分别表示入栈和出栈操作)
    //正确返回true,错误返回false
    int i,j=0,k=0;
//,扫描这个序列任何位置时,O的个数(出栈次序)都小于I的个数(入栈次序),
//若大于,则不合法序列,整个序列都扫描后,O的个数都应该等于I的个数,否则为不合法序列。
    for(i=1;i<=S.length;i++){
       if(S.str[i]=='I'){
        j++;
       }
       else if(S.str[i]=='O'){
        k++;
        if(k>j){
            return false;//当出栈操作多于入栈操作时,不需要判断整个字符串,可以直接返回false
        }
       }
    }
    if(j==k){
        return true;
    }
    else{
        return false;
    }
}
int newstrcat(SString &s1,SString &s2){
    int len1,len2,i,j;
    len1=s1.length+1;
    len2=s2.length+1;
    if(len1+len2>=20){
        for(i=len1,j=1;j+i<=20;i++,j++){
            s1.str[i+1]=s2.str[j];
            s1.length++;
        }
        s1.str[i+1]='\0';
        return 1;
    }
    return 0;
}

main函数定义:

#include"comdef.h"
#include"structdef.h"
#include"stringapp.h"
int main(){
    SString s,t,sub;
    char ch1[maxsize+1];
    int input,compareres,Slength;
    bool strcat,strcopy;
    cout<<"1.输入字符串内容"<<endl;
    cout<<"2.输出字符串内容"<<endl;
    cout<<"3.字符串的长度"<<endl;
    cout<<"4.将字符串t连到字符串s后面"<<endl;
    cout<<"5.比较字符串s和字符串t的大小"<<endl;
    cout<<"6.将字符串t的内容复制到字符串s"<<endl;
    cout<<"7.从字符串的的pos位开始截取len位组成新的字符串"<<endl;
    cout<<"8.在字符串s的第pos位中查找子串t(BF算法)"<<endl;
    cout<<"9.在字符串s的第pos为中查找子串(KMP算法)"<<endl;
    cout<<"10.统计字符串中的A~Z个数"<<endl;
     cout<<"11.判断栈中的序列是否合法"<<endl;
     cout<<"12.20位的strcat"<<endl;
    cout<<"------------------------------------------------------------------"<<endl;
    cin>>input;
    do{
        switch(input){
            case(1):{
                getchar();
                cout<<"请输入一个字符串:"<<endl;
                gets(ch1);
                Inputstring(s,ch1);
                break;
            }
            case(2):{
                cout<<"字符串为:";
                Outputstring(s);
                break;
            }
            case(3):{
                Slength=stringlength(s);
                cout<<"字符串的长度为:"<<Slength<<endl;
                break;
            }
            case(4):{
                cout<<"请输入字符串t的内容:";
                getchar();
                gets(ch1);
                Inputstring(t,ch1);
                strcat=StrCat(s,t);
                int strlen;
                if(strcat){
                    cout<<"已成功将字符串t黏贴到字符串s后面"<<endl;
                    cout<<"新字符串的内容为:";
                    Outputstring(s);
                    cout<<endl;
                    strlen=stringlength(s);
                    cout<<"新字符串的长度为:"<<strlen<<endl;
                }
                else{
                    cout<<"字符串黏贴失败"<<endl;
                }
                break;
            }
            case(5):{
                cout<<"请输入字符串t的内容"<<endl;
                getchar();
                gets(ch1);
                Inputstring(t,ch1);
                compareres=StrCompare(s,t);
                if(compareres==0){
                    cout<<"两个字符串相等"<<endl;
                }
                else if(compareres>0){
                        cout<<"字符串s大于字符串t"<<endl;
                }
                else if(compareres<0){
                    cout<<"字符串s小于字符串t"<<endl;
                }
                break;
            }
            case(6):{
                int strlen;
                cout<<"请输入字符串t的内容:";
                getchar();
                gets(ch1);
                Inputstring(t,ch1);
                strcopy=StringCopy(s,t);
                if(strcopy){
                    cout<<"已成功将字符串t的内容替换为字符串s的内容"<<endl;
                    cout<<"新字符串的内容为:";
                    Outputstring(s);
                    cout<<endl;
                    strlen=stringlength(s);
                    cout<<"新字符串的长度为:"<<strlen<<endl;
                }
                else{
                    cout<<"字符串复制失败"<<endl;
                }
                break;
            }
            case(7):{
                int pos,len,strlen;
                cout<<"请输入想要从哪里开始截取:";
                cin>>pos;
                cout<<"请输入想要截取的位数:";
                cin>>len;
                bool substring;
                substring=SubString(s,sub,pos,len);
                if(substring){
                 cout<<"已成功截取为新的字符串sub"<<endl;
                    cout<<"新字符串的内容为:";
                    Outputstring(sub);
                    cout<<endl;
                    strlen=stringlength(sub);
                    cout<<"新字符串的长度为:"<<strlen<<endl;
                }
                else{
                    cout<<"输入的截取的pos值和len值有误"<<endl;
                }
                break;
            }
            case(8):{
                    getchar();
                    cout<<"请输入子串:";
                    gets(ch1);
                    Inputstring(t,ch1);
                    int pos,res;
                    cout<<"请输入pos位:";
                    cin>>pos;
                    res=Index_BF(s,t,pos);
                    if(res!=0){
                        cout<<"子串查找成功子串,位置在字符串s的"<<res<<"上"<<endl;
                    }
                    else{
                        cout<<"子串查找失败,未能找到子串"<<endl;
                    }
                    break;
            }
            case(9):{
                int next[maxsize];
                    getchar();
                    cout<<"请输入子串:";
                    gets(ch1);
                    Inputstring(t,ch1);
                    int pos,res;
                    cout<<"请输入pos位:";
                    cin>>pos;
                    get_next(t,next);
                    res=Index_KMP(s,t,pos,next);
                    if(res!=0){
                        cout<<"子串查找成功子串,位置在字符串s的"<<res<<"上"<<endl;
                    }
                    else{
                        cout<<"子串查找失败,未能找到子串"<<endl;
                    }
                break;
            }
            case(10):{
                getchar();
                StrCount(s);
                break;
            }
            case(11):{
                getchar();
                cout<<"请输入栈的操作序列:";
                gets(ch1);
                Inputstring(s,ch1);
                bool res=CheckStr(s);
                if(res){
                    cout<<"栈操作合法"<<endl;
                }
                else{
                    cout<<"栈操作不合法"<<endl;
                }
            break;
            }case(12):{
                int res;
            getchar();
            cout<<"请输入第一个字符串:"<<endl;
            gets(ch1);
            Inputstring(s,ch1);
            cout<<"请输入第二个字符串:"<<endl;
            gets(ch1);
            Inputstring(t,ch1);
            res=newstrcat(s,t);
            if(res==1){
               cout<<"新的字符串为"<<endl;
               puts(s.str);
            }
            break;
            }
        }
    cout<<"------------------------------------------------------------------"<<endl;
    cout<<"1.输入字符串内容"<<endl;
    cout<<"2.输出字符串内容"<<endl;
    cout<<"3.字符串的长度"<<endl;
    cout<<"4.将字符串t连到字符串s后面"<<endl;
    cout<<"5.比较字符串s和字符串t的大小"<<endl;
    cout<<"6.将字符串t的内容复制到字符串s"<<endl;
    cout<<"7.从字符串的的pos位开始截取len位组成新的字符串"<<endl;
    cout<<"8.在字符串s的第pos位中查找子串t(BF算法)"<<endl;
    cout<<"9.在字符串s的第pos为中查找子串(KMP算法)"<<endl;
    cout<<"10.统计字符串中的A~Z个数"<<endl;
    cout<<"11.判断栈中的序列是否合法"<<endl;
         cout<<"12.20位的strcat"<<endl;

    cout<<"------------------------------------------------------------------"<<endl;
        cin>>input;
    }while(input!=-1);
}

运行截图:

在这里插入图片描述

二叉树

头文件定义:

#include<iostream>
#include<stack>
#include<queue>
using namespace std;

结构体定义:

typedef char Elemtype;
typedef struct Bitnode{
    int data;
    struct Bitnode* Lchild;
    struct Bitnode* Rchild;
}Bitnode;
typedef Bitnode* Bitree;

函数定义:

void initBitree(Bitree &T){//初始化二叉树
    T=new Bitnode;//创建树节点
    if(T){//如果创建成功就将左子树和右子树置空
        T->Lchild=NULL;
     T->Rchild=NULL;
     cout<<"初始化二叉树成功"<<endl;
    }
    else{//如果创建失败就输出提示语句
     cout<<"初始化二叉树失败"<<endl;
    }
}
void createTree(Bitree &T)//先先序输入二叉树节点
{
    Elemtype ch;
    cin >> ch;
    if(ch == '#')    //读取到 NULL 结点
        T = NULL;    //建立空树,结束递归
    else
    {
        T = new Bitnode;    //生成树的根结点
        T->data = ch;
        createTree(T->Lchild);    //创建根结点的左子树
        createTree(T->Rchild);    //创建根结点的右子树
    }
}
void preorder(Bitree T){//先序输出二叉树,中左右
    if(T){
        cout<<(char)T->data<<" ";//输出根节点
        preorder(T->Lchild);//输出左子树
        preorder(T->Rchild);//输出右子树
    }
}
void inorder(Bitree T){//中序输出二叉树,左中右
    if(T){
        inorder(T->Lchild);//输出左子树
        cout<<(char)T->data<<" ";//输出根节点
        inorder(T->Rchild);//输出右子树
    }
}
void nextorder(Bitree T){//后序输出二叉树,左右中
    if(T){
        nextorder(T->Lchild);//输出左子树
        nextorder(T->Rchild);//输出右子树
        cout<<(char)T->data<<" ";//输出根节点
    }
}
void levelorder(Bitree T){//利用队列结构,层序输出二叉树节点,根节点入队后,出队,并将它的孩子入队,重复进行
    queue<Bitree> que_level;//定义队列
    if(T==NULL){//判空操作
        cout<<"空树"<<endl;
    }
    que_level.push(T);//将根节点入队
    while(!que_level.empty()&&que_level.front()){//直至空队列,结束循环,front():返回队列的第一个对象
        cout<<(char)que_level.front()->data<<' ';//输出队列的第一个节点(根节点)信息
        if(que_level.front()->Lchild!=NULL)//判断是否有左子树
        {
            que_level.push(que_level.front()->Lchild);//将左子树节点入队
        }
        if(que_level.front()->Rchild!=NULL)//判断是否有右子树
        {
            que_level.push(que_level.front()->Rchild);//右子树入队
        }
        que_level.pop();//队列头出队列
    }
}
int DepthBitree(Bitree T){//获得二叉树的深度
    int L_length,R_length;
    if(T==NULL){//子树的深度为0
        return 0;
    }
    else{
        L_length=DepthBitree(T->Lchild);//向左子树挖掘深度
        R_length=DepthBitree(T->Rchild);//向右子树挖掘深度
        if(L_length>R_length){//返回左右子树中较大层数
            return L_length+1;
        }
        else{
            return R_length+1;
        }

    }
}
int LeafCout(Bitree T){//统计二叉树的叶节点
    if(T==NULL){//若为空树,则叶子数为0
        return 0;
    }
    else if(T->Rchild==NULL&&T->Rchild==NULL)//若根节点的左右子树为0,则只有一个叶子
    {
        return 1;
    }
    else{//向左右子树挖掘叶子数
        return LeafCout(T->Lchild)+LeafCout(T->Rchild);
    }
}
int NodeCout(Bitree T){//统计二叉树的节点数
    if(T==NULL)
        return 0;//若为空树,则节点数为0
    else{
        return NodeCout(T->Lchild)+NodeCout(T->Rchild)+1;//挖掘左右子树的节点数
    }
}
int singleBitree(Bitree T){//统计单分支节点数
    if(!T){//若为空树,则节点数为0
        return 0;
    }
    else{
        if(T->Lchild&&!T->Rchild){//若左子树存在并且右子树不存在,返回左子树节点数
            return singleBitree(T->Lchild)+1;
        }
        else{
            if(!T->Lchild&&T->Rchild){//若右子树存在并且左子树不存在,返回右子树节点数
                return singleBitree(T->Rchild)+1;
            }
            else{//若双分支都存在,向下挖掘节点数
                return singleBitree(T->Lchild)+singleBitree(T->Rchild);
            }
        }
}
}
int doubleBitree(Bitree T){//统计双分支节点数
   if(T==NULL){//若为空树,则节点个数为0
    return 0;
   }
   else if(T->Lchild!=NULL&&T->Rchild!=NULL){//当前节点的左右孩子都不为空,则双分支节点个数加一
    return doubleBitree(T->Lchild)+doubleBitree(T->Rchild)+1;
   }
   else{//当前节点只有1歌分支,继续遍历左或右子树,不加一
    return doubleBitree(T->Lchild)+doubleBitree(T->Rchild);
   }
}
void revoluteBiTree(Bitree BT)//将二叉树中每一个节点的左右子树交换
{
	Bitree T;//供左右子树的交换中介用
	if(!(BT)->Lchild && !(BT)->Rchild)//若只有根节点无需交换
		return;
	else//左右子树存在,将左右子树交换
	{
		T=(BT)->Lchild;
		(BT)->Lchild=(BT)->Rchild;
		(BT)->Rchild=T;
	}
	if((BT)->Lchild)//对左子树进行交换
	{
		revoluteBiTree((BT)->Lchild);
	}
	if((BT)->Rchild)//对右子树交换
	{
		revoluteBiTree((BT)->Rchild);
	}
}
void Copy(Bitree T,Bitree &NewT){   //复制二叉树
    if(!T){//若原二叉树为空树,将新的二叉树根节点置为NULL结束copy
        NewT=NULL;
        return ;
    }
    else{//原二叉树不为空
        NewT=new Bitnode;//为新的二叉树申请节点空间
        NewT->data=T->data;//复制根节点
        Copy(T->Lchild,NewT->Lchild);//复制左子树
        Copy(T->Rchild,NewT->Rchild);//复制右子树
    }
}
bool isequals(Bitree T,Bitree NewT){
    if(T==NULL&&NewT==NULL){//两颗二叉树均为空,返回true
        return true;
    }
    if((T==NULL&&NewT!=NULL)||(T!=NULL&&NewT==NULL)){//其中只有一棵树为空
        return false;
    }
    if(T->data!=NewT->data){//根节点值不相同
        return false;
    }
    return isequals(T->Lchild,NewT->Lchild)&&isequals(T->Rchild,NewT->Rchild);
    //两棵树不为空,且根节点值相同,分别比较该节点的左子树,右子树
}

main函数定义:

#include"comdef.h"
#include"bitreeapp.h"
int main(){
    Bitree T,newT,compareT;
    int input,depth,leaf,nodecout;
    cout<<"--------------------------------------------------------------"<<endl;
    cout<<"1.初始化二叉树"<<endl;
    cout<<"2.先序输入二叉树节点"<<endl;
    cout<<"3.先序遍历输出二叉树"<<endl;
    cout<<"4.中序遍历输出二叉树"<<endl;
    cout<<"5.后序遍历输出二叉树"<<endl;
    cout<<"6.层序遍历输出二叉树"<<endl;
    cout<<"7.计算二叉树的深度"<<endl;
    cout<<"8.统计二叉树的叶节点"<<endl;
    cout<<"9.统计二叉树的节点"<<endl;
    cout<<"10.统计二叉树的单分支节点个数"<<endl;
    cout<<"11.统计二叉树的双分支节点个数"<<endl;
    cout<<"12.将二叉树中每一个节点的左右子树交换"<<endl;
    cout<<"13.复制二叉树"<<endl;
    cout<<"14.判断两个二叉树是否相等"<<endl;
    cout<<"15.对一段文本进行Huffman编码和译码"<<endl;
    cout<<"-1.退出程序"<<endl;
    cout<<"--------------------------------------------------------------"<<endl;
    cin>>input;
    do{
       switch(input){
        case(1):{
            initBitree(T);
            break;
        }
        case(2):{
            cout<<"请输入数据"<<endl;
        createTree(T);
        break;
        }
        case(3):{
            cout<<"二叉树的内容为:"<<endl;
        preorder(T);
        cout<<endl;
        break;
        }
        case(4):{
         cout<<"二叉树的内容为:";
        inorder(T);
        cout<<endl;
        break;
        }
        case(5):{
        cout<<"二叉树的内容为:";
        nextorder(T);
        cout<<endl;
        break;
        }
        case(6):{
        cout<<"二叉树的内容为:";
            levelorder(T);
            cout<<endl;
            break;
        }
        case(7):{
            depth=DepthBitree(T);
            cout<<"二叉树的深度为:";
            cout<<depth<<endl;
            break;
        }
        case(8):{
            leaf=LeafCout(T);
            cout<<"叶子数为:";
            cout<<leaf<<endl;
            break;
        }
        case(9):{
            nodecout=NodeCout(T);
            cout<<"节点个数为";
            cout<<nodecout<<endl;
            break;
        }
        case(10):{
            int singlenode;
            singlenode=singleBitree(T);
            cout<<"单分支的节点数为:";
            cout<<singlenode<<endl;
            break;
        }
        case(11):{
        int doublenode;
        doublenode=doubleBitree(T);
        cout<<"双分支的节点数为";
        cout<<doublenode<<endl;
        break;
        }
        case(12):{
            revoluteBiTree(T);
            cout<<"左右子树交换成功"<<endl;
            break;
        }
        case(13):{
        Copy(T,newT);
        cout<<"复制结束"<<endl;
        cout<<"新的二叉树内容为:";
        preorder(newT);
        cout<<endl;
        break;
        }
        case(14):{
            initBitree(compareT);
            cout<<"请输入要比较的树的数据:";
            createTree(compareT);
            bool flag=isequals(T,compareT);
            if(flag){
                cout<<"两个二叉树相同"<<endl;
            }
            else{
                cout<<"两个二叉树不相同"<<endl;
            }
            break;
        }
       }
    cout<<"--------------------------------------------------------------"<<endl;
    cout<<"1.初始化二叉树"<<endl;
    cout<<"2.先序输入二叉树节点"<<endl;
    cout<<"3.先序遍历输出二叉树"<<endl;
    cout<<"4.中序遍历输出二叉树"<<endl;
    cout<<"5.后序遍历输出二叉树"<<endl;
    cout<<"6.层序遍历输出二叉树"<<endl;
    cout<<"7.计算二叉树的深度"<<endl;
    cout<<"8.统计二叉树的叶节点"<<endl;
    cout<<"9.统计二叉树的节点"<<endl;
    cout<<"10.统计二叉树的单分支节点个数"<<endl;
    cout<<"11.统计二叉树的双分支节点个数"<<endl;
    cout<<"12.将二叉树中每一个节点的左右子树交换"<<endl;
    cout<<"13.复制二叉树"<<endl;
    cout<<"14.判断两个二叉树是否相等"<<endl;
    cout<<"-1.退出程序"<<endl;
    cout<<"--------------------------------------------------------------"<<endl;
       cin>>input;
    }while(input!=-1);
}

运行截图:
在这里插入图片描述

图(邻接矩阵)

头文件定义:

#include<iostream>
#include<queue>
using namespace std;
#define MAXInt 32767
#define MVNum 100

结构体文件:

typedef int VerTexType;    //顶点的数据类型是字符型
typedef int Arctype;        //边的权值类型为整型
typedef struct {
    VerTexType vexs[MVNum]; //顶点表
    Arctype arcs[MVNum][MVNum]; //邻接矩阵
    int vexnum,arcnum;  //图的顶点数和边数
    int kind;   //图的种类
}AMGraph;
bool visited[MVNum];    //访问标志数组

函数文件定义:

void CreateWXW(AMGraph &G){ //创建无向网
    cout<<"请输入图的总顶点数和总边数"<<endl;    //输入图的顶点数和边数
    cin>>G.vexnum>>G.arcnum;
    cout<<"请输入各个顶点的值"<<endl;
    for(int i=0;i<G.vexnum;i++){    //输入顶点信息
        cin>>G.vexs[i];
    }
    for(int i=0;i<G.vexnum;i++){    //初始化矩阵
        for(int j=0;j<G.vexnum;j++){
            G.arcs[i][j]=MAXInt;
        }
    }
    int v1,v2;
    int k,w,i,j;

    for(k=0;k<G.arcnum;k++){
        cout<<"请输入边的两个顶点和权值"<<endl;
        cin>>v1>>v2>>w;
        i=v1;  //找到顶点的行
        j=v2;  //找到顶点的列
        G.arcs[i][j]=w;
        G.arcs[j][i]=G.arcs[i][j];
    }
}
void CreateYXW(AMGraph &G){ //创建有向网
    cout<<"请输入图的总顶点数和总边数"<<endl;
    cin>>G.vexnum>>G.arcnum;
    cout<<"请输入各个顶点的值"<<endl;
    for(int i=0;i<G.vexnum;i++){
        cin>>G.vexs[i];
    }
    for(int i=0;i<G.vexnum;i++){
        for(int j=0;j<G.vexnum;j++){
            G.arcs[i][j]=MAXInt;
        }
    }
    int k,w,i,j;
    int v1,v2;
    for(k=0;k<G.arcnum;k++){
        cout<<"请输入边的两个顶点和权值"<<endl;
        cin>>v1>>v2>>w;
        i=v1;
        j=v2;
        G.arcs[i][j]=w;
    }
}
void CreateWXT(AMGraph &G){ //创建无向图
    cout<<"请输入图的总顶点数和总边数"<<endl;
    cin>>G.vexnum>>G.arcnum;
    cout<<"请输入各个顶点的值"<<endl;
    for(int i=0;i<G.vexnum;i++){
        cin>>G.vexs[i];
    }
    for(int i=0;i<G.arcnum;i++){
        for(int j=0;j<G.vexnum;j++){
            G.arcs[i][j]=0;
        }
    }
    int i,j,k;
    int v1,v2;
    for(k=0;k<G.arcnum;k++){
        cout<<"请输入边的两个顶点"<<endl;
        cin>>v1>>v2;
        i=v1;
        j=v2;
        G.arcs[i][j]=1;
        G.arcs[j][i]=G.arcs[i][j];
    }
}
void CreateYXT(AMGraph &G){     //创建有向图
      cout<<"请输入图的总顶点数和总边数"<<endl;
    cin>>G.vexnum>>G.arcnum;
    cout<<"请输入各个顶点的值"<<endl;
    for(int i=0;i<G.vexnum;i++){
        cin>>G.vexs[i];
    }
    for(int i=0;i<G.vexnum;i++){
        for(int j=0;j<G.vexnum;j++){
            G.arcs[i][j]=0;
        }
    }
    int i,j,k;
    int v1,v2;
    for(k=0;k<G.arcnum;k++){
        cout<<"请输入边的两个顶点"<<endl;
        cin>>v1>>v2;
        i=v1;
        j=v2;
        G.arcs[i][j]=1;
    }
}
void inDegree_for_web(AMGraph G){   //求顶点的入度,求每一列的非空数量
    int indegree[G.vexnum];
    int i,j;
    for(i=0;i<G.vexnum;i++){
        indegree[i]=0;  //初始化顶点入度数组
    }
    for(i=0;i<G.vexnum;i++){    //从第一列开始比较,每一行是否有非MAXInt的数存在,存在就说明有入度
        for(j=0;j<G.vexnum;j++){
            if(G.arcs[j][i]!=MAXInt){
                indegree[i]++;
            }
        }
    }
    for(i=0;i<G.vexnum;i++){    //输出打印入度
        cout<<G.vexs[i]<<"的入度为:"<<indegree[i]<<endl;
    }
}
void inDegree_for_graph(AMGraph G){   //求顶点的入度,求每一列的非空数量
    int indegree[G.vexnum];
    int i,j;
    for(i=0;i<G.vexnum;i++){
        indegree[i]=0;  //初始化顶点入度数组
    }
    for(i=0;i<G.vexnum;i++){    //从第一列开始比较,每一行是否有非MAXInt的数存在,存在就说明有入度
        for(j=0;j<G.vexnum;j++){
            if(G.arcs[j][i]!=0){
                indegree[i]++;
            }
        }
    }
    for(i=0;i<G.vexnum;i++){    //输出打印入度
        cout<<G.vexs[i]<<"的入度为:"<<indegree[i]<<endl;
    }
}
void outDegree_for_web(AMGraph G){  //求图的出度,求每一行的非空数量
       int outdegree[G.vexnum];
    int i,j;
    for(i=0;i<G.vexnum;i++){
        outdegree[i]=0;  //初始化顶点入度数组
    }
    for(i=0;i<G.vexnum;i++){    //从第一列开始比较,每一行是否有非MAXInt的数存在,存在就说明有入度
        for(j=0;j<G.vexnum;j++){
            if(G.arcs[i][j]!=MAXInt){
                outdegree[i]++;
            }
        }
    }
    for(i=0;i<G.vexnum;i++){    //输出打印出度
        cout<<G.vexs[i]<<"的出度为:"<<outdegree[i]<<endl;
    }
}
void outDegree_for_graph(AMGraph G){  //求图的出度,求每一行的非空数量
       int outdegree[G.vexnum];
    int i,j;
    for(i=0;i<G.vexnum;i++){
        outdegree[i]=0;  //初始化顶点入度数组
    }
    for(i=0;i<G.vexnum;i++){    //从第一列开始比较,每一行是否有非MAXInt的数存在,存在就说明有入度
        for(j=0;j<G.vexnum;j++){
            if(G.arcs[i][j]!=0){
                outdegree[i]++;
            }
        }
    }
    for(i=0;i<G.vexnum;i++){    //输出打印出度
        cout<<G.vexs[i]<<"的出度为:"<<outdegree[i]<<endl;
    }
}
void DFS_AM_graph(AMGraph G,int v){  //深度遍历
    int i;
    visited[v]=true;
    cout<<v<<" ";
    for(i=0;i<G.vexnum;i++){
        if(G.arcs[v][i]!=0 && (!visited[i])){
            DFS_AM_graph(G,i);
        }
    }
}
void DFS_AM_web(AMGraph G,int v){  //深度遍历
    int i;
    visited[v]=true;
    cout<<v<<" ";
    for(i=0;i<G.vexnum;i++){
        if(G.arcs[v][i]!=MAXInt && (!visited[i])){
            DFS_AM_web(G,i);
        }
    }
}
void Clearvisited(AMGraph G ,bool visited[]){
    for(int i=0;i<G.vexnum;i++){
        visited[i]=false;
    }
}
int Fisrtadjex(AMGraph G,int v){    //返回v的第一个邻接点,不存在换回-1
    int i;
    for(i=0;i<G.vexnum;i++){    //从行的开头对比是否有邻接边
        if((G.arcs[v][i]!=0||G.arcs[v][i]!=MAXInt) && visited[i]==false){
            return i;
        }
    }
    return -1;
}
int Nextadjex(AMGraph G,int u,int w){   //返回v相对于w的下一个邻接点,u是开始节点
    int i;
    for(i=w;i<G.vexnum;i++){
        if((G.arcs[u][i]!=0 && G.arcs[u][i]!=MAXInt) &&visited[i]==false){
            return i;
        }
    }
    return -1;
}
void BFS_AM_graph(AMGraph G,int v){ //从v节点开始广度遍历
    cout<<v<<" ";
    visited[v]=true;
    queue<int> que_level;
    que_level.push(v);
    while(!que_level.empty()){
        int u;
        u=que_level.front();
        que_level.pop();
        for(int w=Fisrtadjex(G,u);w>=0;w=Nextadjex(G,u,w)){
            if(!visited[w])
            {
                cout<<w<<" ";
                visited[w]=true;
                que_level.push(w);
            }
        }
    }
}

main函数定义:

#include"comdef.h"
#include"app.h"

int main(){
    AMGraph G;
    int input;
    cout<<"——————————————————————————————"<<endl;
    cout<<"1.创建图邻接矩阵"<<endl;
    cout<<"2.打印图各个顶点的入度"<<endl;
    cout<<"3.打印图各个顶点的出度"<<endl;
    cout<<"4.深度遍历图"<<endl;
    cout<<"5.广度遍历图"<<endl;
    cout<<"-1,退出程序"<<endl;
    cout<<"——————————————————————————————"<<endl;
    cout<<"你的选择是:";
    cin>>input;
    do{
    switch(input){
        case(1):
        {
           cout<<"请选择创建图的种类   1:无向网 2:有向网 3:无向图  4:有向图"<<endl;
           cin>>G.kind;
           switch(G.kind)
           {
           case(1):
            {
                CreateWXW(G);
                break;
            }
           case(2):
            {
                CreateYXW(G);
                break;
            }
           case(3):
            {
                CreateWXT(G);
                break;
            }
           case(4):
            {
                CreateYXT(G);
                break;
            }
           }
           break;
        }
        case(2):
            {
                switch(G.kind)
                {
                case(1):
                    {
                        inDegree_for_web(G);
                        break;
                    }
                case(2):
                    {
                        inDegree_for_web(G);
                        break;
                    }
                case(3):
                    {
                        inDegree_for_graph(G);
                        break;
                    }
                case(4):
                    {
                        inDegree_for_graph(G);
                        break;
                    }
                }

            break;
            }
        case(3):
            {
                switch(G.kind)
                {
                case(1):
                    {
                        outDegree_for_web(G);
                        break;
                    }
                case(2):
                    {
                        outDegree_for_web(G);
                        break;
                    }
                case(3):
                    {
                        outDegree_for_graph(G);
                        break;
                    }
                case(4):
                    {
                        outDegree_for_graph(G);
                        break;
                    }
                }
                break;
            }
        case(4):
            {
                switch(G.kind)
                {
                case(1):
                    {
                        int i;
                cout<<"请输入开始遍历节点:"<<" ";
                cin>>i;
                DFS_AM_web(G,i);
                Clearvisited(G,visited);
                cout<<endl;
                break;
                    }
                case(2):
                    {
                        int i;
                cout<<"请输入开始遍历节点:"<<" ";
                cin>>i;
                DFS_AM_web(G,i);
                Clearvisited(G,visited);
                cout<<endl;
                break;
                    }
                case(3):
                    {
                        int i;
                cout<<"请输入开始遍历节点:"<<" ";
                cin>>i;
                DFS_AM_graph(G,i);
                Clearvisited(G,visited);
                cout<<endl;
                break;
                    }
                case(4):
                {
                   int i;
                cout<<"请输入开始遍历节点:"<<" ";
                cin>>i;
                DFS_AM_graph(G,i);
                Clearvisited(G,visited);
                cout<<endl;
                break;
                }
                }
                break;
            }
        case(5):
           {
               int i;
               cout<<"请输入开始遍历的节点"<<" ";
               cin>>i;
               BFS_AM_graph(G,i);
               cout<<endl;
               break;
           }

    }
    cout<<"——————————————————————————————"<<endl;
    cout<<"1.创建图邻接矩阵"<<endl;
    cout<<"2.打印图各个顶点的入度"<<endl;
    cout<<"3.打印图各个顶点的出度"<<endl;
    cout<<"4.深度遍历图"<<endl;
    cout<<"5.广度遍历图"<<endl;
    cout<<"-1,退出程序"<<endl;
    cout<<"——————————————————————————————"<<endl;
    cout<<"你的选择是:";
    cin>>input;
    }while(input!=-1);

}

运行截图:
在这里插入图片描述

图(邻接表)

头文件定义:

#include<iostream>
#include<queue>
#include<stack>
#include<stdlib.h>
using namespace std;

#define MAXVEX 100  //最大顶点数

结构体定义:

typedef struct ArcNode{//邻接表节点
    int adjvex;     //邻接点的位置
    struct ArcNode* nextarc;    //指向下一个表的节点的指针
    int weight; //边的权重
}ArcNode;

typedef struct Vnode{
    char data;  //顶点信息
    ArcNode* firstarc;  //指向第一个表节点的指针
}Vnode,AdjList[MAXVEX]; //AdjList表示邻接表类型

typedef  struct ALGraph{
    AdjList vertices;   //头节点数组
    int vexnum,arcnum;      //图的当前顶点数和边数
}ALGraph;

函数定义:

void CreatMGraph(ALGraph &G)    //创建无向图
{
	int i,j,k;
	ArcNode *s;
	cout<<"请输入总顶点数,总边数"<<endl;
	cin>>G.vexnum>>G.arcnum; 	//输入总顶点数,总边数
    cout<<"请输入各个顶点值"<<endl;
	for(i=0;i<G.vexnum;i++){   			//输入各点,构造表头节点表
		cin>>G.vertices[i].data;  //输入顶点值
	}
	for(i=0;i<G.vexnum;i++){
		G.vertices[i].firstarc = NULL;   	//初始化表头节点的指针域为NULL
	}
	for(k=0;k<G.arcnum;k++) {
	    cout<<"请输入一条边的两个节点"<<endl;   			  //输入各边,构造邻接表
		cin>>i>>j;   			  //输入一条边的两个节点
		s=new ArcNode;  // 生成一个新节点
		s->adjvex=j;
		s->nextarc=G.vertices[i].firstarc;  //头插法建立新节点
		G.vertices[i].firstarc = s;
		s=new ArcNode; //生成另一个对称的新的边节点
		s->adjvex=i;
		s->nextarc=G.vertices[j].firstarc;
		G.vertices[j].firstarc = s;
	}
}
void CreatYGraph(ALGraph &G){   //创建有向图
    int i,j,k;
    ArcNode *s;
    cout<<"请输入总顶点数,总边数"<<endl;
    cin>>G.vexnum>>G.arcnum;    //输入总顶点数,总边数
    cout<<"请输入各个顶点值"<<endl;
    for(i=0;i<G.vexnum;i++){
        cin>>G.vertices[i].data;    //输入各点,构造表头节点表
    }
    for(i=0;i<G.vexnum;i++){
        G.vertices[i].firstarc=NULL;    //初始化表头节点的指针域为NULL
    }
    for(k=0;k<G.arcnum;k++){
        cout<<"请输入一条边的两个节点"<<endl;//输入各边,构造邻接表
        cin>>i>>j;
        s=new ArcNode;//生成一个新节点
        s->adjvex=j;
        s->nextarc=G.vertices[i].firstarc;//头插法建立新节点
        G.vertices[i].firstarc=s;
    }

}
void CreatWWGraph(ALGraph &G){  //创建无向网
    int i,j,k,w;
    ArcNode *s;
    cout<<"请输入总结点数和总边数"<<endl;
    cin>>G.vexnum>>G.arcnum;        //输入总顶点数,总边数
    cout<<"请输入各个顶点的值"<<endl;
    for(i=0;i<G.vexnum;i++){
        cin>>G.vertices[i].data;    //输入各点,构造表头节点表
    }
    for(i=0;i<G.vexnum;i++){
        G.vertices[i].firstarc=NULL;    //初始化表头节点的指针域为NULL
    }
    for(k=0;k<G.arcnum;k++){
        cout<<"请输入一条边的两个节点和边上的权重"<<endl;
        cin>>i>>j>>w;   //输入各边节点和权重,构造邻接表
        s=new ArcNode;  //生成一个新节点
        s->adjvex=j;    //把该节点的邻接点的数据置为j
        s->weight=w;    //该节点的所在边的权重
        s->nextarc=G.vertices[i].firstarc;
        G.vertices[i].firstarc=s;   //头插法
        s= new ArcNode;     //创建对称节点
        s->adjvex=i;
        s->weight=w;
        s->nextarc=G.vertices[j].firstarc;
        G.vertices[j].firstarc=s;
    }
}
void CreatYWGraph(ALGraph &G){  //创建有向网
    int i,j,w,k;
    ArcNode *s;
    cout<<"请输入总节点和总边数"<<endl;
    cin>>G.vexnum>>G.arcnum;    //输入总顶点数,总边数
    cout<<"请输入各个顶点的值"<<endl;
    for(i=0;i<G.vexnum;i++){
        cin>>G.vertices[i].data;    //输入各点,构造表头节点表
    }
    for(i=0;i<G.vexnum;i++){
        G.vertices[i].firstarc=NULL;    //初始化表头节点的指针域为NULL
    }
    for(k=0;k<G.arcnum;k++){
        cout<<"请输入一条边上的两个节点和权重"<<endl;
        cin>>i>>j>>w;           //输入各边节点和权重,构造邻接表
        s= new ArcNode;      //生成一个新节点
        s->adjvex=j;        //把该节点的邻接点的数据置为j
        s->weight=w;        //该节点的所在边的权重
        s->nextarc=G.vertices[i].firstarc;
        G.vertices[i].firstarc=s;       //头插法
    }
}
void printfGraph(ALGraph G){    //图专用的邻接图打印
    int i;
    ArcNode *p;
    for(i=0;i<G.vexnum;i++){
        cout<<G.vertices[i].data<<":";
        for(p=G.vertices[i].firstarc;p;p=p->nextarc){
            cout<<p->adjvex<<" ";
        }
        cout<<endl;
    }
}

 void printWGraph(ALGraph G) //网专用的邻接图打印
{
    int i;
	ArcNode *p;
	for(i=0;i<G.vexnum;i++){
		printf("%c:",G.vertices[i].data);
		for(p=G.vertices[i].firstarc;p;p=p->nextarc){
		printf(" %d",p->adjvex);
		printf("边上的权重是:%d",p->weight);
		}
		printf("\n");
}
}
int A[MAXVEX];  //入度数组
void count_in(ALGraph G,int A[]){    //求有向图和有向网的入度
    int i,j;
    for(i=0;i<G.vexnum;i++){
        A[i]=0;     //初始化入度数组
    }
    ArcNode *e;
    for(j=0;j<G.vexnum;j++){    //从邻接表数组的开始统计
        while(G.vertices[j].firstarc!=NULL){    //这个节点有邻接节点
            A[G.vertices[j].firstarc->adjvex]++;    //对应的邻接节点入度加一
            e=G.vertices[j].firstarc->nextarc;      //向下一个节点前进,e为当前邻接节点的下一个节点
            G.vertices[j].firstarc=e;
        }
    }

}
void count_out(ALGraph G){  //求有向图和有向网的出度
    int i,j;
    int A[G.vexnum];
    for(i=0;i<G.vexnum;i++){
        A[i]=0;
    }
    ArcNode *e;
    for(j=0;j<G.vexnum;j++){
        while(G.vertices[j].firstarc!=NULL){
            A[j]++;
            e=G.vertices[j].firstarc->nextarc;
            G.vertices[j].firstarc=e;
        }
    }
    for(i=0;i<G.vexnum;i++){
        cout<<G.vertices[i].data<<"的出度为:"<<A[i]<<endl;
    }
}
bool visited[MAXVEX];

void clearvisited(bool visited[]){  //清空标志数组,方便多次得到深度遍历节点
    for(int i=0;i<MAXVEX;i++){
        visited[i]=false;
    }
}
 void DFS(ALGraph G,int v){ //G为邻接表,从顶点v出发,深度优先搜索遍历.类似于树的先序遍历
    cout<<v<<" ";   //输出第v个节点
    int w;
    visited[v]=true;//置其标志数组对应值为true
    ArcNode *p;
    p=G.vertices[v].firstarc;   //p指向v的边链表的第一个边节点
    while(p!=NULL){             //边节点非空
        w=p->adjvex;            //w是v的邻接点
        if(!visited[w]){        //如果w未访问,则递归调用
            DFS(G,w);
        }
        p=p->nextarc;   //p指向下一个边节点
    }
 }
int FisAdjVex(ALGraph G,int V){ //找到v的第一个邻接点
    int i,k;
    for(i=0;i<G.vexnum;i++){
        if(i==V){
            k=G.vertices[i].firstarc->adjvex;
            return k;
        }
    }
    return -1;  //未找到邻接点
}
int nextAdjVex(ALGraph G,int v,int w){  //找到v相对于w的下一个邻接点
    int k;
    ArcNode *p;
    if(w<0){
        return -1;  //没有邻接点了
    }
    else{
        for(p=G.vertices[v].firstarc;p;p=p->nextarc){
            if(p->adjvex==w){
                if(p->nextarc!=NULL){
                    k=p->nextarc->adjvex;
                    return k;
                }
            }
        }
    }
    return -1;
}
int locateVertex(ALGraph G,char v){ //找到对应顶点的下标
    for(int i=0;i<G.vexnum;i++){    //比对表头数据,找到就返回所在位置,没找到就返回-1
        if(G.vertices[i].data==v){
            return i;
        }
    }
    return -1;
}
void BFS_AL(ALGraph G,char v0){ //邻接表的广度遍历,类似于树的层序遍历
    int i,j,v;
    ArcNode *p;
    cout<<v0<<" ";  //打印顶点v0
    i=locateVertex(G,v0);   //找到v0对应的下标
    visited[i]=true;        //顶点已被访问
    queue<char> que_level;  //创建队列
    que_level.push(v0);     //将顶点v0入队
    while(!que_level.empty()){
        v=que_level.front();    //将顶点元素v出队,开始访问v的所有邻接点
        i=locateVertex(G,v);    //得到顶点u的对应下标
        que_level.pop();
        for(p=G.vertices[i].firstarc;p;p=p->nextarc){       //遍历顶点v的邻接点
            j=p->adjvex;    //j是v的邻接点
            if(!visited[j]){    //如果顶点p未被访问
                cout<<G.vertices[j].data<<" ";  //打印顶点p
                visited[j]=true;        //顶点p已被访问
                que_level.push(G.vertices[j].data); //将顶点p入队
            }
        }
    }

}
void Toposort(ALGraph G){
    count_in(G,A);  //初始化建立各个顶点的入度表
    stack<int> S;   //建立空栈
    int Nodecount=0;    //拓扑排序检测
    int v;
    cout<<"拓扑序列:"<<endl;
    for(int i=0;i<G.vexnum;i++){
        if(A[int(G.vertices[i].data-'0')]==0){  //假如节点的入度为0,就进栈
            S.push(i);
        }
    }
    while(!S.empty()){  //当栈为非空
        v=S.top();  //得到栈的栈顶
        S.pop();    //弹栈
        cout<<v<<" ";//输出拓扑排序序列
        Nodecount++;
        ArcNode *temp;
        temp=G.vertices[v].firstarc;//指向v的第一个邻接点
        while(temp!=NULL){
            A[int(G.vertices[temp->adjvex].data-'0')]--;//v的每个邻接点入度减一
            if(A[int(G.vertices[temp->adjvex].data-'0')]==0){   //若入度减为0,入栈
                S.push(temp->adjvex);
            }
            temp=temp->nextarc;//指向下一个邻接点
        }
    }
    if(Nodecount<G.vexnum){    //判断是否有回路
        cout<<"图有回路"<<endl;
    }
}


main函数定义:

#include"comdef.h"
#include"app.h"

int main(){
    ALGraph G;
    int input,kind,v;
    char v0;
    cout<<"——————————————————————————————"<<endl;
    cout<<"\t1.创建无向图/有向图/无向网/有向网(邻接表)"<<endl;
    cout<<"\t2.打印邻接表"<<endl;
    cout<<"\t3.深度遍历"<<endl;
    cout<<"\t4.计算有向图/网的入度"<<endl;
    cout<<"\t5.计算有向图/网的出度"<<endl;
    cout<<"\t6.广度遍历"<<endl;
    cout<<"\t7.求AOV网的拓扑序列"<<endl;
    cout<<"\t-1,退出程序"<<endl;
    cout<<"——————————————————————————————"<<endl;
    cout<<"你的选择是:";
    cin>>input;
    do{
    switch(input){
        case(1):
        {
            cout<<"1.无向图"<<endl;
            cout<<"2.有向图"<<endl;
            cout<<"3.无向网"<<endl;
            cout<<"4.有向网"<<endl;
            cout<<"请选择创建图的类型:";
            cin>>kind;
            switch(kind){
            case(1):
                {
                    CreatMGraph(G);
                    break;
                }
            case(2):
                {
                    CreatYGraph(G);
                    break;
                }
            case(3):
                {
                    CreatWWGraph(G);
                    break;
                }
            case(4):
                {
                    CreatYWGraph(G);
                    break;
                }
            }
           break;
        }
        case(2):
            {
                switch(kind){
                    case(1):{
                        printfGraph(G);
                        break;
                    }
                    case(2):{
                        printfGraph(G);
                    break;
                    }
                    case(3):{
                        printWGraph(G);
                        break;
                    }

                    case(4):{
                        printWGraph(G);
                        break;
                    }
                }
                break;
            }
        case(3):
            {
                cout<<"请输入开始深度遍历节点:"<<" ";
                cin>>v;
                DFS(G,v);
                clearvisited(visited);
                cout<<endl;
                break;
            }
        case(4):
            {
                count_in(G,A);
                for(int i=0;i<G.vexnum;i++){
                cout<<G.vertices[i].data<<"的入度为:"<<A[i]<<endl;
                }
                break;
            }
        case(5):
            {
                count_out(G);
                break;
            }
        case(6):
            {
                cout<<"请输入开始广度遍历节点:"<<" ";
                cin>>v0;
               BFS_AL(G,v0);
               clearvisited(visited);
               cout<<endl;
               break;
            }
            case(7):
                {
                   Toposort(G);
                   cout<<endl;
                   break;
                }
    }
    cout<<"——————————————————————————————"<<endl;
    cout<<"\t1.创建无向图/有向图/无向网/有向网(邻接表)"<<endl;
    cout<<"\t2.打印邻接表"<<endl;
    cout<<"\t3.深度遍历"<<endl;
    cout<<"\t4.计算有向图/网的入度"<<endl;
    cout<<"\t5.计算有向图/网的出度"<<endl;
    cout<<"\t6.广度遍历"<<endl;
    cout<<"\t7.求AOV网的拓扑序列"<<endl;
    cout<<"\t-1,退出程序"<<endl;
    cout<<"——————————————————————————————"<<endl;
    cout<<"你的选择是:";
    cin>>input;
    }while(input!=-1);

}

运行截图:
在这里插入图片描述

查找

头文件定义:

#include<iostream>
#include<random>
using namespace std;
typedef int keytype;
#define  MAXLEN 100

结构体定义:

typedef struct{
    keytype key;
}Elemtype;
typedef struct{
    Elemtype R[MAXLEN+1];
    int length;
}SSTable;
typedef SSTable* seq;

函数定义:

void Createseq(seq &ST,int num){    //创建顺序表,向表中输入num个数据
    for(int i=1;i<=num;i++){
           cout<<"请输入数据"<<" ";
        cin>>ST->R[i].key;
    }
    ST->length=num;
}
int search_bin(seq ST,keytype key){  //折半查找,
    int low=1,mid;
    int high=ST->length;
    while(low<=high){
        mid=(low+high)/2;
        if(key==ST->R[mid].key){ //找到待查元素
            return mid;
        }
        else if(key<ST->R[mid].key){ //就绪在前一子表进行查找
            high=mid-1;
        }
        else{
            low=mid+1;  //在后一子表查找
        }
    }
    return 0;       //表中不存在待查元素
}
void search_seq(seq ST,keytype num){
    int i;
    for(i=ST->length;i>=1;i--){
        if(ST->R[i].key==num)
        {
          cout<<"该元素的位置为:"<<i<<endl;
            break;
        }
    }
    if(i==0){
        cout<<"该元素不在该表中"<<endl;
    }
}

main函数定义:

#include"comdef.h"
#include"app.h"

int main(){
    int input;
    seq ST;
    cout<<"1.输入顺序表序列"<<endl;
    cout<<"2.顺序查找"<<endl;
    cout<<"3.折半查找"<<endl;
    cout<<"——————————————————————————"<<endl;
    cin>>input;
    do
    {
        switch(input)
        {
        case(1):
            {
                int num;
                cout<<"请输入顺序表的个数:"<<" ";
                cin>>num;
                Createseq(ST,num);
                cout<<"输入结束"<<endl;
                break;
            }
        case(2):
            {
                int key;
                cout<<"请输入欲查找数据"<<endl;
                cin>>key;
                search_seq(ST,key);
                break;
            }
        case(3):
            {
                keytype key;
                 cout<<"请输入欲查找数据"<<endl;
                cin>>key;
                int res=search_bin(ST,key);
                if(res!=0)
                {
                    cout<<"该元素的位置为:"<<res<<endl;
                }
                else{
                    cout<<"该元素不在顺序表中"<<endl;
                }
                break;
            }
        }

    cout<<"1.输入顺序表序列"<<endl;
    cout<<"2.顺序查找"<<endl;
    cout<<"3.折半查找"<<endl;
    cout<<"——————————————————————————"<<endl;
    cin>>input;
    }while(input!=-1);
}

运行截图:
在这里插入图片描述

排序和二叉排序树

排序

头文件定义:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define MAXSIZE 100

结构体定义:

typedef int ElemType;
typedef struct {
    ElemType *data;
    int length;
}sqlist;

函数定义:

void init(sqlist &L){   //初始化顺序表
    L.data= new ElemType [MAXSIZE+1];
    if(L.data==NULL)
    {
        cout<<"未申请到空间"<<endl;
    }
    L.length=MAXSIZE;
}
void Create_raw_data(sqlist &L){    //产生一个无序待排数据
    for(int i=1;i<L.length;i++)
    {
        L.data[i]=rand()%100;
    }
}
void destroydata(sqlist &L){
    delete L.data;
    cout<<"销毁成功"<<endl;
}
void show(sqlist L){
    for(int i=1;i<L.length;i++)
    {
        cout<<L.data[i]<<" ";
    }
}
void InsertSort(sqlist &L){ //对顺序表进行直接排序
    int i,j;
    for(i=2;i<=L.length;i++){
        if(L.data[i]<L.data[i-1])
        {
            L.data[0]=L.data[i];    //将待插入的记录暂存到监视哨
            for(j=i-1;L.data[0]<L.data[j];j--){ //在前i-1大小的已排好序的子表中查找需要插入的位置
                L.data[j+1]=L.data[j];  //记录逐个后移,直至找到插入位置
            }
            L.data[j+1]=L.data[0];  //将r[0]即原r[i],插入正确位置
        }
    }
    cout<<"插入排序成功!"<<endl;
}
void Bubblesort(sqlist &L){
    int m=L.length-1,flag=1;    //flage用来标记某一趟排序是否发生交换
    while((m>0)&&(flag==1))
    {
        flag=0; //flag置为0,如果本趟排序没有发生交换,则不会执行下一趟排序
        for(int j=1;j<=m;j++){
            if(L.data[j]>L.data[j+1])
            {
                flag=1; //flag置为1,表示本趟发生了交换
                int t=L.data[j];
                L.data[j]=L.data[j+1];
                L.data[j+1]=t;  //交换前后两个记录
            }
        }
        m--;
    }
    cout<<"冒泡排序成功"<<endl;
}
int Partition(sqlist &L,int low,int high){ //对顺序表L中的子表r[low..high]进行排序,韩慧枢轴位置
    L.data[0]=L.data[low];  //用子表的第一个记录做枢轴记录
    int privotkey=L.data[low];  //枢轴记录关键字保存在privotkey中
    while(low<high)
    {
        while(low<high&&L.data[high]>=privotkey)
        {
            high--;
        }
        L.data[low]=L.data[high];   //将比枢轴记录小的记录移到低端
        while(low<high&&L.data[low]<=privotkey)
        {
            low++;
        }
        L.data[high]=L.data[low];   //将比枢轴记录大的记录移到高端
    }
    L.data[low]=L.data[0];  //枢轴记录到位
    return low;     //返回枢轴位置
}
void Qsort(sqlist &L,int low,int high){ //d对顺序表中的子序列L.data[low..high]做快速排序
    if(low<high){   //长度大于1
        int pivotloc=Partition(L,low,high); //将L.data[low..high]一分为二,pivotloc是枢轴位置
        Qsort(L,low,pivotloc-1);    //对左子表递归排序
        Qsort(L,pivotloc+1,high);//对右子表递归排序
    }
}
void Quicksort(sqlist &L){  //快速排序
    Qsort(L,1,L.length);
}

main函数定义:

#include"comdef.h"
#include"app.h"
int main(){
    sqlist L;
    int input;
    cout<<"——————————————————————"<<endl;
    cout<<"1.生成随机待排数据"<<endl;
    cout<<"2.查看数据"<<endl;
    cout<<"3.进行直接插入排序"<<endl;
    cout<<"4.冒泡排序"<<endl;
    cout<<"5.快速排序"<<endl;
    cout<<"6.销毁数据"<<endl;
    cout<<"——————————————————————"<<endl;
    cin>>input;
    do
    {
        switch(input)
        {
        case(1):
            {
                init(L);
                Create_raw_data(L);
                break;
            }
        case(2):
            {
                show(L);
                cout<<""<<endl;
                break;
            }
        case(3):
            {
                InsertSort(L);
                break;
            }
        case(4):
            {
                Bubblesort(L);
                break;
            }
        case(5):
            {
                Quicksort(L);
                break;
            }
        case(6):
            {
               destroydata(L);
               break;
            }
        }


    cout<<"——————————————————————"<<endl;
    cout<<"1.生成随机待排数据"<<endl;
    cout<<"2.查看数据"<<endl;
    cout<<"3.进行直接插入排序"<<endl;
    cout<<"4.冒泡排序"<<endl;
    cout<<"5.快速排序"<<endl;
    cout<<"6.销毁数据"<<endl;
    cout<<"——————————————————————"<<endl;
    cin>>input;
    }while(input!=-1);
}

运行截图:

在这里插入图片描述

二叉排序树:

头文件和结构体定义:

#include<iostream>
using namespace std;
typedef int elemtype;
typedef struct Bsnode{
    elemtype data;
    struct Bsnode* lchild;
    struct Bsnode* rchild;
}Bsnode;
typedef Bsnode* Bstree;

函数定义:

void InsertBST(Bstree &T,elemtype e){   //当二叉排序树中不存在关键字等于e的数据元素时,就插入该元素
    Bstree s;
    if(!T){
        s=new Bsnode;
        s->data=e;
        s->lchild=NULL;
        s->rchild=NULL;
        T=s;
    }
    else if(e<T->data)
        InsertBST(T->lchild,e);
    else if(e>T->data)
        InsertBST(T->rchild,e);
}
void CreateBST(Bstree &T){
    int e;
    T=NULL;
    cout<<"请输入二叉排序树的内容,输入1024时结束"<<" ";
    cin>>e;
    while(e!=1024){
        InsertBST(T,e);
        cin>>e;
    }
}
void printBTS(Bstree T){    //输出二叉排序树的内容
    if(T){
        printBTS(T->lchild);
        cout<<T->data<<" ";
        printBTS(T->rchild);
    }
}

main函数定义:

#include"comdef.h"
#include"app.h"

int main(){
    int input;
    Bstree T;
    cout<<"\t1.创建二叉排序树"<<endl;
    cout<<"\t2.为二叉排序树插入一个节点"<<endl;
    cout<<"\t3.输出二叉排序树的数据序列"<<endl;
    cout<<"\t-1.退出程序"<<endl;
    cout<<"----------------------------------------------------"<<endl;
    cout<<"您的选择是:"<<"" ;
    cin>>input;
    do
    {
        switch(input)
        {
        case(1):
            {
                CreateBST(T);
                break;
            }
        case(2):
            {
                elemtype e;
                cout<<"请输入插入的数据值"<<" ";
                cin>>e;
                InsertBST(T,e);
                break;
            }
        case(3):
            {
                printBTS(T);
                cout<<endl;
                break;
            }
        }
    cout<<"\t1.创建二叉排序树"<<endl;
    cout<<"\t2.为二叉排序树插入一个节点"<<endl;
    cout<<"\t3.输出二叉排序树的数据序列"<<endl;
    cout<<"\t-1.退出程序"<<endl;
    cout<<"----------------------------------------------------"<<endl;
    cout<<"您的选择是:"<<"" ;
    cin>>input;
    }while(input!=-1);
}

运行截图:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值