数据结构 算法 我花了一学期整理的

一:线性表

1.单链表应用

例子一:尾插入创立单链表,并且删除相同元素,即表示一个集合

#include<iostream>

using namespace std;

struct node

{

  int num;

  struct node *next;

};

node *head;

void  creat_list()

{

   int N,i;

   cin>>N;

   node*temp,*tail;

   head=new node;

   tail=head;

   tail->next=NULL;

   for(i=0;i<=N-1;i++)

     {

        temp=new node;

        if(temp==NULL)

        {

          cout<<"memory allocate fail and exit";

          exit(1);  

        }

       cin>>temp->num;

       tail->next=temp;

       tail=temp;

       tail->next=NULL;

    }     

}

 

void out_put_list()

{

    node* a=head->next;

    while(a!=NULL)

    {

       cout<<a->num<<" ";

       a=a->next;

     }

    cout<<endl;

}

 

void delete_list()

{

    node *p,*q,*r;

    p=head->next;

    while(p)

    {

        q=p;

        while(q->next)

        {

            if((q->next)->num==p->num)

            {

               r=q->next;

               q->next=r->next;

               free(r);

            }

            else q=q->next;

        }

        p=p->next;

    }

}

int main(void)

{

    creat_list();

    out_put_list();

    delete_list();

    out_put_list();

    return 0;

}

例题二:把单链表L的元素按类型分为三个单链表

#include<iostream>

#include <ctype.h>

using namespace std;

typedef struct Lnode{

    char data;

    struct Lnode *next;

}Lnode,*LinkList;

typedef struct List{

    LinkList head;

    int n;

}List;

void InitLinkList(List &l)

{

    l.head=new Lnode;

    l.head->next=NULL;

    l.n=0;

}//InitLinkList

void CreateLinkList(List &l)

{

    cout<<"请输入链表的元素个数:";

    cin>>l.n;

    cout<<"请输入链表的元素:";

    LinkList q=l.head;

    for(int i=0;i<l.n;i++)

    {

        LinkList p=new Lnode;

        cin>>p->data;

        q->next=p;

        q=p;

    }

    q->next=NULL;

}//CreateLinkList

void SplitLinkList(List &l,List &a,List &b,List &c)

{

    LinkList s=l.head->next;

    LinkList p=a.head;

    LinkList q=b.head;

    LinkList r=c.head;

    while(s)

    {

        if(isalpha(s->data))

        {

            p->next=s;

            p=s;

            a.n++;

        }

        else if(isdigit(s->data))

        {

            q->next=s;

            q=s;

            b.n++;

        }

        else{

            r->next=s;

            r=s;

            c.n++;

        }

        s=s->next;

    }

    p->next=NULL;

    q->next=NULL;

    r->next=NULL;

    delete []l.head;

}//SplitLinkList

void ShowLinkList(List l)

{

    cout<<"该链表的元素个数:"<<l.n<<endl;

    cout<<"该链表的元素:";

    LinkList p=l.head->next;

    while(p)

    {

        cout<<p->data;

        p=p->next;

    }

    cout<<endl;

}//ShowLinkList

int main(){

    List l;

    InitLinkList(l);

    CreateLinkList(l);

    List Sq1,Sq2,Sq3;//字母,数字,其他

    InitLinkList(Sq1);

    InitLinkList(Sq2);

    InitLinkList(Sq3);

    SplitLinkList(l,Sq1,Sq2,Sq3);

    cout<<"字母字符链表如下:"<<endl;

    ShowLinkList(Sq1);

    cout<<"数字字符链表如下:"<<endl;

    ShowLinkList(Sq2);

    cout<<"其他字符链表如下:"<<endl;

    ShowLinkList(Sq3);

    return 0;

}

 

例子三:用拷贝构造函数及构造函数创建单链表,并逆序创建单链表

#include<iostream>

#include<iomanip>

using namespace std;

struct node

{

   int score;

   char num[15];

   char name[20];

   node *next;

};

 

class linklist{

private:

    node *head;

    node *tail;

    int length;

public:

    linklist(int m)

    {

        length=m;

        head=new node;

        head->next=NULL;

        tail=head;

        cout<<"Input "<<length<<" students'imformation of linklist you want:"<<endl;

        cout<<left<<setw(20)<<"name"<<left<<setw(20)<<"num"

        <<left<<setw(20)<<"score"<<endl;

        int i;

        for(i=0;i<=length-1;i++)

        {

            node *temp=new node;

            cin>>temp->name>>temp->num>>temp->score;

            temp->next=NULL;

            tail->next=temp;

            tail=temp;

        }

    }

 

    void show()

    {

        if(length==0)

            cout<<"It's an empty linklist!"<<endl;

        else

        {

            node *t=head->next;

            cout<<"Output "<<length<<" students'imformation of linklist:"<<endl;

            cout<<left<<setw(20)<<"name"<<left<<setw(20)<<"num"

            <<left<<setw(20)<<"score"<<endl;

            while(t!=NULL)

            {

              cout<<left<<setw(20)<<t->name<<left<<setw(20)<<t->num

              <<left<<setw(20)<<t->score<<endl;

              t=t->next;

            }

        }

    }

 

    linklist(const linklist &s)

    {

        length=s.length;

        head=new node;

        head->next=NULL;

        tail=head;

        node *t=s.head->next;

        while(t!=NULL)

        {

            node *temp=new node;

            strcpy(temp->name,t->name);

            strcpy(temp->num,t->num);

            temp->score=t->score;

            temp->next=NULL;

            tail->next=temp;

            tail=temp;

            t=t->next;

        }

    }

 

    ~linklist()

    {

        node *r,*p;

        if(length==0) delete head;

        else

        {

           p=head->next;

           while(head->next!=NULL)

           {

               r=p;

               head->next=r->next;

               delete r;

               p=head->next;

           }

           delete head;

        }

        cout<<"delete....!"<<endl;

    }

 

     linklist()

     {

         head=new node;

         head->next=NULL;

         tail=head;

         node *temp=new node;

         strcpy(temp->name,"xiaodong");

         strcpy(temp->num,"0825121006");

         temp->score=85;

         temp->next=NULL;

         tail->next=temp;

         tail=temp;

         length=1;

     }

 

   void reverse_linklist()

   {

       node *q=head->next;

       node *r=head;

       node *s;

       while(q->next!=NULL)

       {

         node *p=head;

         while((p->next)->next!=NULL)

             p=p->next;

         s=r->next;

         r->next=p->next;

         (p->next)->next=s;

         p->next=NULL;

         r=r->next;

       }

   }

 

};

int main()

{

    linklist list(5);

    list.show();

    linklist mylist(list);

    mylist.show();

    linklist youlist;

    youlist.show();

    list.reverse_linklist();

    list.show();

    return 0;

}

例子四:约瑟夫环顺序表实现代码

#include<stdio.h>

#include<stdlib.h>

#define LIST_INIT_SIZE 100

#define LISTINCREMENT 10

typedef struct{

    int ID;

    int Code;

}ElemType;

 

typedef struct{

    ElemType *elem;

    int length;

    int listsize;

}SqList;

 

void InitList_Sq(SqList &L){

     L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType)); //申请结点空间

     if(!L.elem) exit(0);                                        //申请失败,关闭程序

     L.length=0;                                                 //空表长度为0

     L.listsize=LIST_INIT_SIZE;                                  //初始存储容量

}//InitList_Sq

 

void CreateList_Sq(SqList &L,int n){

    if(n>L.listsize){                                            //判断存储空间是否足够

        ElemType *base=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));

        if(!base) exit(0);                                       //不够再分配

        L.elem=base;                                             //指针指向新分配空间的首地址

        L.listsize+=LISTINCREMENT;                               //修改存储容量

    }

    printf("请输入这%d人的密码(>0):",n);                       

    for(int i=0;i<n;i++){

        L.elem[i].ID=i+1;

        scanf("%d",&(L.elem[i].Code));                           //输入n个人的密码

    }

    L.length+=n;                                                 //修改表长度                  

}//CreateList_Sq

 

void DeleteList_Sq(SqList &L,int &m,int &start_pos){  //start_pos为新一轮报数的首个元素的下标

    m=(start_pos+m)%L.length;          //用取余数的方法寻找报数为m的元素,可减少搜索的次数

    if(m==0) m=L.length;               //如果报数为m的元素是数组的最后一个元素,要加上表的本身长度

    start_pos=m-1;                     //记录下一轮开始报数的首元素的数组下标

    ElemType *q=L.elem+L.length-1;     //q指向最后一个元素

    ElemType *p=&(L.elem[m-1]);        //p指向报数为m的元素

    printf("%d ",p->ID);               //打印删除元素的编号,即出列编号

    m=p->Code;                         //保存下一轮报数的密码

    for(;p<q;p++) *p=*(p+1);           //左移覆盖

    --L.length;                        //修改表长

}//DeleteList_Sq

 

int main(){

    SqList L;

    int n,m,start_pos(0);     //start_pos为新一轮报数的首元素的下标,初始化为0

    printf("请输入初始报数(m>0):");

    scanf("%d",&m);

    while(m<=0){              //检查报数的合法性

         printf("请重新输入初始报数(m>0):");

         scanf("%d",&m);

    }

    printf("请输入用户数(0<n):");

    scanf("%d",&n);

    while(n<=0){              //检查用户数的合法性

         printf("请重新输入用户数(n>0):");

         scanf("%d",&n);

    }

    InitList_Sq(L);          //初始化顺序表

    CreateList_Sq(L,n);      //创建顺序表

    for(int i=n;i>=1;i--)    //根据报数,删除报数为m的元素,并输出出列编号,

        DeleteList_Sq(L,m,start_pos);   //循环n次,即删除所有元素,顺序表为空时停止循环

    printf("/n");

    return 0;

}//main

 

例子五:约瑟夫环循环链表实现代码

#include<stdio.h>

#include<stdlib.h>

typedef struct{

    int ID;

    int Code;

    }ElemType;

 

typedef struct Lnode{

ElemType elem;

    struct Lnode *next;

}Lnode,*LinkList;

 

void CreateList_L(LinkList &L,int n){

    L=(LinkList)malloc(sizeof(Lnode));   //申请结点空间

    if(!L) exit(0);                      //申请失败,关闭程序

    LinkList p=L;

    printf("请输入这%d人的密码:",n);   

    for(int i=1;i<=n;i++){

      p->elem.ID=i;                     //为这n个人编号

      scanf("%d",&(p->elem.Code));      //输入每个人的密码

      if(i==n) break;                   //如果i等于第n个人,无需再申请结点空间,跳出循环

      p->next=(LinkList)malloc(sizeof(Lnode)); //申请下一个结点空间

      if(!(p->next)) exit(0);          //如果申请失败,关闭程序

      p=p->next;                       //指针移动到下一个结点

    }

    p->next=L;                        //首尾相连,构成循环链表

}//CreateList_L

 

 

void DeleteList_L(LinkList &L,int &m,int Length){

    int j=m%Length;               //用取余数的方法寻找报数为m的结点,可减少循环

                                 //遍历的次数

    if(j==0||j==1) j+=Length;   //如果m是首结点或是尾结点,要加上链表的本身长

                           //度,目的是寻找报数为m-1的结点,删除m结点就比较方便

    int i=1;

    while(i++<j-1) L=L->next;  //寻找要删除结点的前驱结点

    m=L->next->elem.Code;      //先保存下一轮报数的密码

    printf("%d ",L->next->elem.ID);  //打印删除结点的编号,即出列编号

    LinkList p=L->next;              //保存要删除结点的地址

    L->next=p->next;                 //断开删除结点,即出列,重新连接链表

    L=L->next;                      //移动指针到下一个结点,等待下一轮新的报数

    free(p);                       //删除报数为m的结点

}//DeleteList_L

 

void main(){

    LinkList L=NULL;          //初始化为空链表

    int n,m;

    printf("请输入初始报数(m>0):");

    scanf("%d",&m);

    while(m<=0){              //检查报数的合法性

         printf("请重新输入初始报数(m>0):");

         scanf("%d",&m);

    }

    printf("请输入用户数(0<n):");

    scanf("%d",&n);

    while(n<=0){              //检查用户数的合法性

         printf("请重新输入用户数(n>0):");

         scanf("%d",&n);

    }

    CreateList_L(L,n);       //创建循环链表

    for(int i=n;i>=1;i--)    //根据报数,删除结点,输出出列编号,

      DeleteList_L(L,m,i);  //循环n次,即删除所有结点,链表为空时停止循环

    printf("/n");

}//main

 

例子六:单链表建立及按顺序输出

#include<iostream>

#include<cstdlib>

using namespace std;

struct node

{

  int data;

  struct node *next;

};

void main(void)

{

   const int N=10;

   node *head,*temp,*tail;

   head=new node;

   head->next=NULL;

   tail=head;

   for(int i=0;i<=N-1;i++)

    {

        temp=new node;

        if(temp==NULL)

        {

            cout<<"memory allocate fail and exit";

           exit(1);  

        }

        cin>>temp->data;

        temp->next=NULL;

        tail->next=temp;

        tail=temp;

       

    }

   head=head->next;

   int t;

   node *p;

   for(i=0;i<=N-2;i++)

   {

       for(int j=0;j<=N-i-2;j++)

       {

           if(head->data<(head->next)->data)

           {

               t=(head->next)->data;

               (head->next)->data=head->data;

               head->data=t;

           }

           if(j==0)

               p=head;

           head=head->next;

       }

      head=p;

   }

   while(head!=NULL)

    {

       cout<<head->data<<" ";

       head=head->next;

     }

   cout<<endl;

}

 

例子七:建立单循环链表,并连接两个单循环链表

#include<iostream>

using namespace std;

 

struct node{

    int data;

    node *next;

};

 

class linklist{

private:

    node *head;

    node *rear;

    int length;

public:

    linklist(int n){

        length=n;

        head=new node;

        head->next=head;

        rear=head;

        int i;

        for(i=0;i<=length-1;++i){

            node *temp=new node;

            cin>>temp->data;

            temp->next=head;

            rear->next=temp;

            rear=temp;

        }

    }

 

   void show(){

        node *s=head->next;

        while(s!=head){

            cout<<s->data<<" ";

            s=s->next;

        }

        cout<<endl;

    }

 

   ~linklist(){

        if(length==0)

            delete head;

        else{

              node *r;

              while(head->next!=head){

                r=head->next;

                head->next=r->next;

                delete r;

            }

            delete head;

        }

        cout<<"delete..........!"<<endl;

    }

 

   void connect_list(linklist &l){

        node *front=new node;

        front->next=front;

        node *tail=front;

        node *p=l.head->next;

        while(p!=l.head){

            node *temp=new node;

            temp->data=p->data;

            temp->next=front;

            tail->next=temp;

            tail=temp;

            p=p->next;

        }

        rear->next=front->next;

        tail->next=head;

        delete front;

    }

};

int main()

{

    linklist a(4);

    a.show();

    linklist b(5);

    b.show();

    b.connect_list(a);

    b.show();

    return 0;

}

 

例子八:两个单链表互相连接

#include<iostream>

using namespace std;

 

struct node {

    int data;

    node *next;

};

 

class linklist {

 

private:

    node *head;

    node *rear;

    int length;

public:

    linklist(int n){

        length=n;

        head=new node;

        head->next=NULL;

        rear=head;

        int i;

        for(i=0;i<=length-1;++i){

            node *temp=new node;

            cin>>temp->data;

            temp->next=NULL;

            rear->next=temp;

            rear=temp;

        }

    }

 

    void show(){

        node *s=head->next;

        while(s!=NULL){

            cout<<s->data<<" ";

            s=s->next;

        }

        cout<<endl;

    }

 

    ~linklist(){

        if(length==0)

            delete head;

        else{

            node *r;

            while(head->next!=NULL){

                r=head->next;

                head->next=r->next;

                delete r;

            }

            delete head;

        }

        cout<<"delete..........!"<<endl;

    }

   

    void connect_list(linklist &l){

        node *h=new node;

        h->next=NULL;

        node *tail=h;

        node *p=l.head->next;

        while(p!=NULL){

            node *temp=new node;

            temp->data=p->data;

            temp->next=NULL;

            tail->next=temp;

            tail=temp;

            p=p->next;

        }

        rear->next=h->next;

        delete h;

    }

 

    linklist(const linklist &l){

        head=new node;

        head->next=NULL;

        rear=head;

        node *p=l.head->next;

        while(p!=NULL){

            node *temp=new node;

            temp->data=p->data;

            temp->next=NULL;

            rear->next=temp;

            rear=temp;

            p=p->next;

        }

    }

 

};

 

    int main(){

        linklist a(3);

        a.show();

        linklist b(5);

        b.show();

        linklist c(a);

        a.connect_list(b);

        a.show();

        b.connect_list(c);

        b.show();

        return 0;

    }

例子九:双向链表的头插入建表

#include<iostream>

using namespace std;

 

struct node{

    int data;

    node *next;

    node *prior;

};

 

class linklist{

private:

    node *head;

    node *rear;

    int length;

public:

    linklist(int n){

        length=n;

        head=new node;

        head->next=NULL;

        rear=head;

        node *temp=new node;

        cin>>temp->data;

        temp->prior=head;

        temp->next=NULL;

        head->next=temp;

        rear=temp;

        node *s=temp;

        int i;

        for(i=0;i<=length-2;++i){

            node *temp=new node;

            cin>>temp->data;

            head->next=temp;

            temp->prior=head;

            temp->next=s;

            s->prior=temp;

            s=s->prior;

        }

    }

 

   void show(){

        node *s=head->next;

        while(s!=NULL){

            cout<<s->data<<" ";

            s=s->next;

        }

        cout<<endl;

    }

 

   void display(){

       node *s=rear;

       while(s!=head){

           cout<<s->data<<" ";

           s=s->prior;

       }

       cout<<endl;

   }

/*

 

   ~linklist(){

        if(length==0)

            delete head;

        else{

              node *r;

              while(head->next!=NULL){

                r=head->next;

                head->next=r->next;

                delete r;

            }

            delete head;

        }

        cout<<"delete..........!"<<endl;

    }*/

 

   //也可以从尾结点开始删除结点

  

   ~linklist(){

        if(length==0)

            delete head;

        else{

              node *r;

              while(head->next!=NULL){

                r=rear;

                r->prior->next=NULL;

                rear=rear->prior;

                delete r;

            }

            delete head;

        }

        cout<<"delete..........!"<<endl;

    }

 

};  

int main()

{

    linklist a(4);

    a.display();

        a.show();

    return 0;

}

例子十:双向循环链表的建立

#include<iostream>

using namespace std;

 

struct node{

    int data;

    node *next;

    node *prior;

};

 

class linklist{

private:

    node *head;

    node *rear;

    int length;

public:

    linklist(int n){

        length=n;

        head=new node;

        head->next=head;

        head->prior=head;

        rear=head;

        int i;

        for(i=0;i<=length-1;++i){

            node *temp=new node;

            cin>>temp->data;

            temp->next=head;

            temp->prior=rear;

            rear->next=temp;

            head->prior=temp;

            rear=temp;

        }

    }

 

   void show(){

        node *s=head->next;

        while(s!=head){

            cout<<s->data<<" ";

            s=s->next;

        }

        cout<<endl;

    }

 

   void display(){

       node *s=head->prior;

       while(s!=head){

           cout<<s->data<<" ";

           s=s->prior;

       }

       cout<<endl;

   }

 

/*

   ~linklist(){

        if(length==0)

            delete head;

        else{

              node *r;

              while(head->next!=head){

                r=head->next;

                head->next=r->next;

                delete r;

            }

            delete head;

        }

        cout<<"delete..........!"<<endl;

    }*/

 

  

    ~linklist(){

        if(length==0)

            delete head;

        else{

              node *r;

              while(head->prior!=head){

                r=head->prior;

                head->prior=r->prior;

                delete r;

            }

            delete head;

        }

        cout<<"delete..........!"<<endl;

    }

 

 

   void connect(linklist &l){

       length+=l.length;

        node *front=new node;

        front->next=front;

        front->prior=front;

        node *tail=front;

        node *p=l.head->next;

        while(p!=l.head){

            node *temp=new node;

            temp->data=p->data;

            temp->next=front;

            temp->prior=tail;

            tail->next=temp;

            front->prior=temp;

            tail=temp;

            p=p->next;

        }

        rear->next=front->next;

        head->prior=tail;

        tail->next=head;

        front->next->prior=rear;

        delete front;

    }

 

   void company(linklist &l){

        length+=l.length;

        node *front=new node;

        front->next=front;

        front->prior=front;

        node *tail=front;

        node *p=l.head->prior;

        while(p!=l.head){

            node *temp=new node;

            temp->data=p->data;

            temp->next=front;

            temp->prior=tail;

            tail->next=temp;

            front->prior=temp;

            tail=temp;

            p=p->prior;

        }

        rear->next=front->next;

        head->prior=tail;

        tail->next=head;

        front->next->prior=rear;

        delete front;

   }

 

   void joint(linklist &l){

        length+=l.length;

        node *front=new node;

        front->next=front;

        front->prior=front;

        node *tail=front;

        node *p=l.head->next;

        while(p!=l.head){

            node *temp=new node;

            temp->data=p->data;

            temp->next=front;

            temp->prior=tail;

            tail->next=temp;

            front->prior=temp;

            tail=temp;

            p=p->next;

        }

        head->prior=front->next;

        rear->next=tail;

        tail->next=rear;

        front->next->prior=head;

        delete front;

   }

 

  /* void output(){

       int i;

       node *s=head->next;

       for(i=0;i<=2;i++) {

           cout<<s->data<<" ";

           s=s->next;

        }

       for(i=3;i<=length-1;i++){

           cout<<s->data<<" ";

           s=s->prior;

       }

       cout<<endl;

   }*/

};

 

int main()

{

    linklist a(4);

    a.show();

    a.display();

    linklist b(5);

    b.show();

    b.display();

    linklist c(3);

    c.show();

    c.display();

    linklist d(3);

    d.show();

    d.display();

    b.connect(a);

    b.show();

    b.display();

    c.company(a);

    c.show();

    c.display();

 // d.joint(a);    //output函数的方法不采用,原因如下:

//  d.output();    //必须采用分段输出,不然会死循环

    return 0;      //析构时将只析构尾结点和头结点,将无法清理干净.

}

例子十一:双向循环链表的删除和插入

#include<iostream>

using namespace std;

 

struct node{

    int data;

    node *next;

    node *prior;

};

 

class linklist{

private:

    node *head;

    node *rear;

    int length;

public:

    linklist(int n){

        length=n;

        head=new node;

        head->next=head;

        head->prior=head;

        rear=head;

        int i;

        for(i=0;i<=length-1;++i){

            node *temp=new node;

            cin>>temp->data;

            temp->next=head;

            temp->prior=rear;

            rear->next=temp;

            head->prior=temp;

            rear=temp;

        }

    }

 

   void show(){

        node *s=head->next;

        while(s!=head){

            cout<<s->data<<" ";

            s=s->next;

        }

        cout<<endl;

    }

 

   void display(){

       node *s=head->prior;

       while(s!=head){

           cout<<s->data<<" ";

           s=s->prior;

       }

       cout<<endl;

   }

 

/*

   ~linklist(){

        if(length==0)

            delete head;

        else{

              node *r;

              while(head->next!=head){

                r=head->next;

                head->next=r->next;

                delete r;

            }

            delete head;

        }

        cout<<"delete..........!"<<endl;

    }*/

 

  

    ~linklist(){

        if(length==0)

            delete head;

        else{

              node *r;

              while(head->prior!=head){

                r=head->prior;

                head->prior=r->prior;

                delete r;

            }

            delete head;

        }

        cout<<"delete..........!"<<endl;

    }

 

    void insert(int m,int elem){

        node *s=head;

        int i;

        if(m>=(length+1/2))

            for(i=0;i<=length-m;++i)

                s=s->prior;

        else

            for(i=0;i<=m-1;++i)

                   s=s->next;

        node *temp=new node;

        temp->data=elem;

        s->prior->next=temp;

        temp->prior=s->prior;

        temp->next=s;

        s->prior=temp;

        length++;

    }

 

    void deletelist(int m){

        node *s=head;

        int i;

        if(m>=((length+1)/2))

            for(i=0;i<=length-m;++i)

                s=s->prior;

        else

            for(i=0;i<=m-1;++i)

                s=s->next;

        s->prior->next=s->next;

        s->next->prior=s->prior;

        delete s;

        length--;

    }

 

};

int main()

{

    linklist a(7);

    a.show();

    a.insert(3,10);

    a.show();

    a.deletelist(4);

    a.show();

    return 0;

}

例子十二:头插入建立单链表

#include<iostream>

using namespace std;

struct node

{

   int data;

   node *next;

};

class linklist{

private:

    node *head;

    int length;

public:

    linklist(int m)

    {

        length=m;

        head=new node;

        head->next=NULL;

        node *tail=new node;

        cin>>tail->data;

        tail->next=NULL;

        head->next=tail;

        node *s=tail;

        int i;

        for(i=0;i<=length-2;i++)

        {

            node *temp=new node;

            cin>>temp->data;

            head->next=temp;

            temp->next=s;

            s=temp;

        }

    }

 

    void display()

    {

        if(length==0)

            cout<<"It's an empty linklist!"<<endl;

        else

        {

           node *p=head->next;

           while(p!=NULL)

           {

              cout<<p->data<<" ";

              p=p->next;

           }

           cout<<endl;

        }

    }

 

    ~linklist()

    {

        if(length==0)

            delete head;

        else

        {

            node *r;

            while(head->next!=NULL)

            {

                r=head->next;

                head->next=r->next;

                delete r;

            }

            delete head;

            cout<<"delete........!"<<endl;

        }

    }

 

};

int main()

{

    linklist mylist(5);

    mylist.display();

    return 0;

}

备注:其他顺序表,单链表,循环链表,双向循环链表的创建,增删改查,两个链表的连接,逆序创建链表等参照数据结构的伪代码和自己理解,适当修改即可用。

 

二:栈和队列

备注:有现成的模板库可以调用,一般不单独考,可能在非递归,遍历用到栈和队列的操作。

 

 

 

 

三:树和二叉树

例子一:二叉树三种递归遍历代码

#include<iostream>

using namespace std;

typedef struct node

{

    char ch;

    struct node *lchild,*rchild;

}*BiTree;

void CreateBiTree(BiTree &T){            //创建二叉树

    char ch;

    scanf("%c",&ch);

    if(ch=='#') T=NULL;

    else{

        T=new node;

        T->ch=ch;

        CreateBiTree(T->lchild);

        CreateBiTree(T->rchild);

    }

}

void PreOrder(BiTree T){               //先序递归遍历二叉树

    if(T){

        printf("%c",T->ch);

        if(T->lchild) PreOrder(T->lchild);

        if(T->rchild) PreOrder(T->rchild);

    }

}

void InOrder(BiTree T){                //中序递归遍历二叉树

    if(T){

        InOrder(T->lchild);

        printf("%c",T->ch);

        InOrder(T->rchild);

    }

}

void PostOrder(BiTree T){              //后序递归遍历二叉树

    if(T){

        PostOrder(T->lchild);

        PostOrder(T->rchild);

        printf("%c",T->ch);

    }

}

int main(){

    BiTree T;

    CreateBiTree(T);

    printf("先序遍历结果:");          

    PreOrder(T);                     

    printf("/n");

    printf("中序遍历结果:");       

    InOrder(T);

    printf("/n");

    printf("后序遍历结果:");     

    PostOrder(T);

    printf("/n");

    return 0;

}

 

例子二:二叉树四种非递归遍历(其中三种各有三种不同的方法实现)代码

#include<iostream>

#include<stack>

#include<queue>

using namespace std;

typedef struct node

{

    char ch;

    struct node *lchild,*rchild;

}*BiTree; //二叉树

typedef struct{

    BiTree ptr;

    int tag;  //标志位 

}Mark_BiTree; //标志二叉树

void CreateBiTree(BiTree &T){

    //先序次序创建二叉树

    char ch;

    scanf("%c",&ch);

    if(ch=='#') T=NULL;

    else{

        T=new node;

        T->ch=ch;

        CreateBiTree(T->lchild);

        CreateBiTree(T->rchild);

    }

}

void PreOrder(BiTree T){

    //利用栈先序遍历二叉树非递归算法

    //方法一:这里采用广度遍历入栈,类似层序遍历,不过是从上到下,从右到左。

    stack<BiTree> s;  //初始化栈

    if(T){

        s.push(T);    //根结点入栈

        while(!s.empty())

        {

            BiTree p=s.top();

            s.pop();    //出栈

            printf("%c",p->ch);

            if(p->rchild) s.push(p->rchild); //右孩子入栈

            if(p->lchild) s.push(p->lchild); //左孩子入栈

        }

    }

    //方法二:这里采用深度遍历入栈,空结点也入栈

    /*stack<BiTree> s;  //初始化栈

    s.push(T);        //根结点入栈

    while(!s.empty())

    {

        BiTree p=s.top(); //取栈顶元素

        while(p)

        {

          printf("%c",p->ch);

          s.push(p->lchild); //左孩子入栈

          p=p->lchild;       //p指向左孩子

        }

        s.pop();             //空结点出栈

       if(!s.empty())

        {

            p=s.top();      //取栈顶元素

            s.pop();        //出栈

            s.push(p->rchild);//右孩子入栈

       }

    }*/

    //方法三:这里采用深度遍历入栈的另外一种版本,空结点不入栈

    /*stack<BiTree> s;       //初始化栈

    BiTree p=T;            //初始化p

    while(p||!s.empty())

    {

        if(p)

        {

            printf("%c",p->ch);

            s.push(p);    //入栈

            p=p->lchild;  //p指向左孩子

        }

        else

        {

            p=s.top();   //取栈顶元素

            s.pop();     //出栈

            p=p->rchild; //p指向右孩子

        }

    }*/

}

void InOrder(BiTree T){

    //利用栈中序遍历二叉树非递归算法

    //方法一:这里采用深度遍历入栈,空结点入栈

    /*stack<BiTree> s;    //初始化栈

    s.push(T);          //根结点入栈

    while(!s.empty())

    {

        BiTree p=s.top();//取栈顶元素

        while(p)

        {

            s.push(p->lchild);//左孩子入栈

            p=s.top();//p=p->lchild//p指向左孩子

        }

        s.pop();        //空结点出栈

        if(!s.empty())

        {

            p=s.top();  //取栈顶元素

            s.pop();    //出栈

            printf("%c",p->ch);

            s.push(p->rchild);//右孩子入栈

        }

    }*/

    //方法二:这里采用深度遍历入栈的另外一种版本,空结点不入栈

    stack<BiTree> s;   //初始化栈

    BiTree p=T;        //初始化p

    while(p||!s.empty())

    {

        if(p)

        {

            s.push(p);//入栈

            p=p->lchild;//p指向左孩子

        }

        else

        {

            p=s.top();//取栈顶元素

            s.pop();  //出栈

            printf("%c",p->ch);

            p=p->rchild; //p指向右孩子

        }

    }

    //方法三:这里采用广度遍历入栈

    //tag=0,表示只有该结点入栈

    //tag=1;表示该结点和左右孩子按中序入栈

    /*stack<Mark_BiTree> s; //初始化栈

    Mark_BiTree e;     //定义标志二叉树

    BiTree p=T;        //初始化p

    if(T){

        e.ptr=p;     

        e.tag=0;      //初始标志位:0

        s.push(e);    //根结点入栈

        while(!s.empty())

        {

            e=s.top(); //获取栈顶元素

            s.pop();   //出栈

            p=e.ptr;

            if(e.tag==0)//只有该结点入栈

            {

                if(p->rchild){

                e.tag=0;  //右孩子初始化

                e.ptr=p->rchild;//右孩子入栈

                s.push(e);

                }

                e.ptr=p; //重新设置标志位

                e.tag=1; //表示该结点再次入栈,左右孩子也入栈

                s.push(e);

                if(p->lchild){

                e.tag=0;  //左孩子初始化

                e.ptr=p->lchild;//左孩子入栈

                s.push(e);

                }

            }

            else{    //若该结点入栈,左右孩子也入栈,输出该结点值

                printf("%c",e.ptr->ch);

            }  

        }

    }*/

}

void PostOrder(BiTree T){

    //利用栈和标志位后序遍历二叉树非递归算法

    //方法一:深度遍历入栈

    //tag=0,表示该结点暂不处理,往左子树去

    //tag=1;表示该结点可处理,从右子树回来

    stack<Mark_BiTree> s; //初始化栈

    BiTree p=T;   //初始化p

    Mark_BiTree e;//定义标志二叉树

    while(p||!s.empty())

    {

        if(p)

        {

            e.tag=0;e.ptr=p;

            s.push(e); //该结点暂不处理,入栈,往左子树去

            p=p->lchild;

        }

        else

        {

            e=s.top();//获取栈顶元素

            s.pop();  //出栈

            int fag=e.tag; //获取标志位

            p=e.ptr;

            if(fag==0)

            {

                e.tag=1;//从左子树回来,往右子树去

                s.push(e); //修改标志位,入栈

                p=p->rchild;

            }

            else

            {

                printf("%c",p->ch);//从右子树回来,处理结点

                p=NULL;   //p置空,继续获取栈顶元素

            }

        }

    }

    //方法二:广度遍历入栈

    //tag=0,表示只有该结点入栈

    //tag=1;表示该结点和左右孩子按后序入栈

    /*stack<Mark_BiTree> s; //初始化栈

    Mark_BiTree e;    //定义标志二叉树

    BiTree p=T;       //初始化p

    if(T){

        e.ptr=p;

        e.tag=0;      //初始标志位:0

        s.push(e);   //根结点入栈

        while(!s.empty())

        {

            e=s.top();  //获取栈顶元素

            p=e.ptr;  

            if(e.tag==0)//只有该结点入栈

            {

                s.top().tag=1;//重新设置标志位,表示左右孩子也入栈

                if(p->rchild){

                e.tag=0; //右孩子初始化

                e.ptr=p->rchild;//右孩子入栈

                s.push(e);

                }

                if(p->lchild){

                e.tag=0;//左孩子初始化

                e.ptr=p->lchild;//左孩子入栈

                s.push(e);

                }

            }

            else{  //若该结点入栈,左右孩子也入栈,输出该结点值

                printf("%c",e.ptr->ch);

                s.pop(); //该结点出栈

            }  

        }

    }*/

    //方法三:方法一的另一种版本,采用深度遍历入栈

    //为了区分两次过栈的不同处理方式,在二叉树中增加一个标志位,tag=0表示刚刚访问此结点,

    //tag=1表示处理了左子树,从左子树回来,tag=2表示处理了右子树,

    //从右子树回来.每次根据栈顶元素的tag值决定做何种动作.

    /*if(T)

    {

        Mark_BiTree e;  //定义标志二叉树

        stack<Mark_BiTree> s; //初始化栈

        BiTree p=T;   //初始化p

        e.ptr=T;

        e.tag=0;     //标志位初始化

        s.push(e);  //根结点入栈

        while(!s.empty())

        {

            e=s.top(); //获取栈顶元素

            p=e.ptr;

            s.pop();  //出栈

            switch(e.tag)//根据标志位,选择不同处理方式

            {

            case 0: //该结点刚入栈

                e.tag=1; //修改标志位

                e.ptr=p;

                s.push(e); //该结点再次入栈

                if(e.ptr->lchild)

                {

                    e.ptr=e.ptr->lchild;

                    e.tag=0; //左子树初始化

                    s.push(e);//左子树入栈

                }

                break;

            case 1:    //从左子树回来,开始处理右子树

                e.tag=2; //修改标志位

                e.ptr=p;

                s.push(e); //该结点再次入栈

                if(e.ptr->rchild)

                {

                    e.ptr=e.ptr->rchild;

                    e.tag=0;//右子树初始化

                    s.push(e);//右子树入栈

                }

                break;

            case 2:

                printf("%c",p->ch);//从右子树回来,可以处理该结点

            }

        }

    }*/

}

void LayerOrder(BiTree T){

    //利用队列层序遍历二叉树非递归算法

    queue<BiTree> q; //初始化队列

    if(T){

        q.push(T);  //入队

        while(!q.empty())

        {

            BiTree p=q.front();//获取队首元素

            q.pop();  //出队

            printf("%c",p->ch);

            if(p->lchild) q.push(p->lchild);//左孩子入队

            if(p->rchild) q.push(p->rchild);//右孩子入队

        }

    }

}

int main(){

    BiTree T;

    CreateBiTree(T);  //创建二叉树

    printf("先序遍历结果:");          

    PreOrder(T);                      

    printf("/n");

    printf("中序遍历结果:");   

    InOrder(T);

    printf("/n");

    printf("后序遍历结果:");        

    PostOrder(T);

    printf("/n");

    printf("层序遍历结果:");        

    LayerOrder(T);

    printf("/n");

    return 0;

}

例子三:Kruskal并查集实现最小生成树

#define MAX 100

#include <iostream>  

using namespace std;  

struct edge  

{  

    int cost;  

    int first;  

    int second;  

};  

int set[MAX];  

edge my_pair[MAX];

int rank[MAX];

int FindSet(int x)

{

    if(set[x]!=x)

        set[x]=FindSet(set[x]);

    return set[x];

}

void MakeSet(int n)

{

    for(int i=1;i<=n;i++){

        set[i]=i;rank[i]=0;

    }

void Link(int a,int b)

{

    if(rank[a]>rank[b])

        set[b]=a;

    else if(rank[a]<rank[b])

        set[a]=b;

    else

    {

        set[a]=b;

        rank[b]++;

    }

}

void Union(int a,int b)

{

    Link(FindSet(a),FindSet(b));

}

int my_cmp(const void* a,const void* b)  

{    

    return (*(edge*)a).cost-(*(edge*)b).cost;        

}  

int main()  

{  

    int N,M,lowcost(0),i,count(1);

    scanf("%d%d",&N,&M);  

    MakeSet(N);

    for(i=0;i<M;i++)  

    {  

        scanf("%d%d%d",&my_pair[i].first,&my_pair[i].second,&my_pair[i].cost);  

    }  

    qsort(my_pair,M,sizeof(edge),my_cmp);  

    for(i=0;i<M&&count<N;i++)  

    {

        int first_root=FindSet(my_pair[i].first);

        int second_root=FindSet(my_pair[i].second);

        if(first_root!=second_root)  

        {  

            Union(first_root,second_root);

            printf("%d----%d/n",my_pair[i].first,my_pair[i].second);

            lowcost+=my_pair[i].cost;

            count++;

        }

    }

    printf("%d/n",lowcost); 

    return 0;  

}

 

例子四:二叉排序树

#include <iostream>

using namespace std;

 struct BiTree{

    int data;

    struct BiTree *lchild,*rchild;

};

 BiTree *T;

void CreateOrderBiTree(int x)

{

    BiTree *node=new BiTree;

    node->data=x;

    node->lchild=node->rchild=NULL;

    if(!T) T=node;

    else

    {

        BiTree *back;

        BiTree *cur=T;

        while(cur)

        {

            back=cur;

            if(cur->data>x)

                cur=cur->lchild;

            else cur=cur->rchild;

        }

        if(back->data>x)

            back->lchild=node;

        else back->rchild=node;

    }

}

void InOrder(BiTree *bt)

{

    if(bt)

    {

        InOrder(bt->lchild);

        cout<<bt->data<<" ";

        InOrder(bt->rchild);

    }

}

int main(){

    T=NULL;

    int n,i,a;

    cin>>n;

    for(i=0;i<n;i++)

    {

        cin>>a;

        CreateOrderBiTree(a);

    }

    InOrder(T);

    cout<<endl;

    return 0;

}

 

例子四:二叉树操作汇集

#include<iostream>

#include<stack>

using namespace std;

typedef struct node

{

    char ch;

    struct node *lchild,*rchild;

    int nodecount;

}BiTNode,*BiTree;

void PreOrder(BiTree T){

    //先序递归遍历二叉树

    if(T){

        printf("%c",T->ch);

        if(T->lchild) PreOrder(T->lchild);

        if(T->rchild) PreOrder(T->rchild);

    }

}

void PostOrder(BiTree T){              //后序递归遍历二叉树

    if(T){

        PostOrder(T->lchild);

        PostOrder(T->rchild);

        printf("%c:%d ",T->ch,T->nodecount);

    }

}

void CreateBiTree(BiTree &T){

    //创建二叉树

    char ch;

    scanf("%c",&ch);

    if(ch=='#') T=NULL;

    else{

        T=new BiTNode;

        T->ch=ch;

        CreateBiTree(T->lchild);

        CreateBiTree(T->rchild);

    }

}

void CountLeaf(BiTree T,int &Count){

    //统计二叉树叶子结点的个数

    if(T){

        if((!T->lchild)&&(!T->rchild))

            Count++;

        CountLeaf(T->lchild,Count);

        CountLeaf(T->rchild,Count);

    }

}

int Leaf_Count(BiTree T)//求二叉树中叶子结点的数目

{

    //统计二叉树叶子结点的个数另一种版本

    if(!T) return 0; //空树没有叶子

    else if(!T->lchild&&!T->rchild) return 1; //叶子结点

    else{

        int m=Leaf_Count(T->lchild);

        int n=Leaf_Count(T->rchild);

        return (m+n);

        //return Leaf_Count(T->lchild)+Leaf_Count(T->rchild);//左子树的叶子数加上右子树的叶子数

    }  

}

void BiTreeDepth(BiTree T,int level,int &depth){

    //求二叉树的深度

    //levelT所指结点所在层次,初值为1

    //depth为当前求得的最大层次,初值为0.

    if(T)

    {

        if(level>depth) depth=level;

        BiTreeDepth(T->lchild,level+1,depth);

        BiTreeDepth(T->rchild,level+1,depth);

    }

}

int DepthOfBiTree(BiTree T){

    //求二叉树深度的另一种版本

    if(!T) return 0;

    else

    {

        int m=DepthOfBiTree(T->lchild);

        int n=DepthOfBiTree(T->rchild);

        //if(m>n) return (m+1);

        //else return (n+1);

        return (m>n?m:n)+1;

    }

}

void Depth_BiTree(BiTree T,int &depth){

    //求二叉树深度的第三种版本

    if(!T) depth=0;

    else

    {

        int m,n;

        Depth_BiTree(T->lchild,m);

        Depth_BiTree(T->rchild,n);

        depth=(m>n?m:n)+1;

    }

}

BiTNode *GetTreeNode(char ch,BiTree lptr,BiTree rptr){

    //生成一个元素值为ch,左指针为lptr,右指针为rptr的结点

    BiTree T=new BiTNode;

    T->ch=ch;

    T->lchild=lptr;

    T->rchild=rptr;

    return T;

}

BiTNode *CopyTree(BiTree T){

    //已知二叉树的根指针,返回复制后的根指针

    BiTree newlptr,newrptr;

    if(!T) return NULL;

    if(T->lchild)

        newlptr=CopyTree(T->lchild);

    else newlptr=NULL;

    if(T->rchild)

        newrptr=CopyTree(T->rchild);

    else newrptr=NULL;

    BiTree newnode=GetTreeNode(T->ch,newlptr,newrptr);

    return newnode;

}

void BiTree_Copy(BiTree T,BiTree &U)

{

    //非递归复制二叉树,有错误

    stack<BiTree> s1,s2;

    s1.push(T); //根指针进栈

    BiTree q=U,p;

    while(!s1.empty())

    {

        p=s1.top();

        q=s2.top();

        while(p)

        {

            q=new BiTNode;

            q->ch=p->ch;

            s1.push(p->lchild);

            p=p->lchild;

            q=q->lchild;

            s2.push(q);

        }//向左走到尽头

        s1.pop();

        s2.top()=NULL;

        s2.pop();

        if(!s1.empty())

        {

            p=s1.top();

            s1.pop();

            s1.push(p->rchild);//向右一步

            q=s2.top();

            s2.pop();

            q=q->rchild;

        }

    }

}

void eularTour(BiTree T,int &Count)//欧拉路径遍历

{

    //统计每个结点后代的数目

    int temp=Count;

    if(T->lchild) eularTour(T->lchild,++Count);

    if(T->rchild) eularTour(T->rchild,++Count);

    printf("%c:%d ",T->ch,Count-temp);

}

int NodeCount(BiTree T)

{

    //统计每个结点后代的数目的另一种方法

    if(!T) return 0;

    return (T->nodecount=NodeCount(T->lchild)+NodeCount(T->rchild))+1;

}

int CountNode(BiTree T){

    //统计二叉树中所有结点的数目

    if(!T) return 0;

    if(!T->lchild&&!T->rchild) return 1;

    else

    {

        int m=CountNode(T->lchild);

        int n=CountNode(T->rchild);

        return (m+n+1);

        //return CountNode(T->lchild)+CountNode(T->rchild)+1;

    }

}

void Count_Node(BiTree T,int &num){

    //统计二叉树中所有结点的数目的另一种版本

    if(T)

    {

        num++;

        Count_Node(T->lchild,num);

        Count_Node(T->rchild,num);

    }

}

int main(){

    BiTree T;

    CreateBiTree(T);

    printf("二叉树所有结点的个数:%d/n",CountNode(T));

    int num=0;

    Count_Node(T,num);

    printf("二叉树所有结点的个数的另一种版本:%d/n",num);

    int Count=0;

    CountLeaf(T,Count);

    printf("二叉树叶子结点的个数:%d/n",Count);

    printf("二叉树叶子结点的个数的另一种版本:%d/n",Leaf_Count(T));

    int depth=0;

    BiTreeDepth(T,1,depth);

    printf("二叉树的深度为:%d/n",depth);

    printf("二叉树深度的另一种版本:%d/n",DepthOfBiTree(T));

    depth=0;

    Depth_BiTree(T,depth);

    printf("二叉树深度的另一种版本:%d/n",depth);

    BiTree bt=CopyTree(T);

    printf("递归复制过后的二叉树:");

    PreOrder(bt);

    printf("/n");

    //BiTree U;//有错误

    //BiTree_Copy(T,U);

    //printf("非递归复制过后的二叉树:");

    //PreOrder(U);

    //printf("/n");

    printf("二叉树每个结点后代的数目:");

    int nodecount=0;

    eularTour(T,nodecount);

    printf("/n");

    printf("二叉树每个结点后代的数目的另一种方法:");

    NodeCount(T);

    PostOrder(T);

    printf("/n");

    return 0;

}

 

四:图和图的遍历

例子一:邻接表表示图的深度遍历和广度遍历

#define MAX_VERTEX_NUM 20 //顶点个数

#include<iostream>

#include<string>

#include<queue> //队列头文件

using namespace std;

typedef int AdjType;

typedef string VexType;

bool visited[MAX_VERTEX_NUM]; //标记是否采访过

typedef struct ArcNode      //采用邻接表作为存储结构,实现无向图的遍历

{

    AdjType adj;

    struct ArcNode *nextarc;

}ArcNode;

typedef struct VertexNode

{

    VexType data;

    ArcNode *firstarc;

}AdjList;

typedef struct ALGraph

{

    AdjList vertex[MAX_VERTEX_NUM];

    int vexnum,arcnum;

}ALGraph;

void Insert_ArcNode(int i,int j,ALGraph &G)//插入某一条边

{

    ArcNode *p=new ArcNode;

    p->adj=j;

    //p->nextarc=G.vertex[i].firstarc;//采用头插入法

    //G.vertex[i].firstarc=p;

    ArcNode *q=G.vertex[i].firstarc;//按顺序插入

    if(!q||j<q->adj)//若为空值或者即将插入的结点序号小于首结点的序号

    {

        p->nextarc=q;//插入首结点之前

        G.vertex[i].firstarc=p;

    }

    else

    {

        while(q->nextarc&&j>q->nextarc->adj)//寻找插入位置

            q=q->nextarc;

        p->nextarc=q->nextarc;//插入该结点之前

        q->nextarc=p;

    }

}

void Init_ALGraph(ALGraph &G)//初始化图

{

    int i,j,k;

    printf("请输入图的顶点数:");

    cin>>G.vexnum;

    printf("请输入图的边数:");

    cin>>G.arcnum;

    printf("请输入顶点的数值:");

    for(k=0;k<G.vexnum;k++)

        cin>>G.vertex[k].data;

    for(k=0;k<G.arcnum;k++)

        G.vertex[k].firstarc=NULL;//置空值

    printf("请输入相关联的边:/n");

    for(k=0;k<G.arcnum;k++)

    {

        cin>>i>>j;

        Insert_ArcNode(i-1,j-1,G);//插入该边

        Insert_ArcNode(j-1,i-1,G);

    }

}

void DFS(ALGraph G,int i)//深入优先搜索

{

    visited[i]=true;

    cout<<G.vertex[i].data<<" ";

    ArcNode *p=G.vertex[i].firstarc;

    while(p)

    {

        i=p->adj;

        if(!visited[i])

            DFS(G,i);

        p=p->nextarc;

    }

}

void DFSTraverse(ALGraph G)

{

    memset(visited,false,sizeof(visited));//赋初值

    for(int i=0;i<G.vexnum;i++)

        if(!visited[i])//遍历各个顶点

            DFS(G,i);

}

void BFS(ALGraph G,int i)//宽度优先搜索

{

    queue<int> q;//初始化队列

    q.push(i);

    visited[i]=true;//采访过

    cout<<G.vertex[i].data<<" ";//输出

    while(!q.empty())

    {

        i=q.front();

        q.pop();

        ArcNode *p=G.vertex[i].firstarc;

        while(p)

        {

            i=p->adj;

            if(!visited[i])

            {

                q.push(i);

                visited[i]=true;

                cout<<G.vertex[i].data<<" ";

            }

            p=p->nextarc;

        }

    }

}

void BFSTraverse(ALGraph G)

{

    memset(visited,false,sizeof(visited));

    for(int i=0;i<G.vexnum;i++)

        if(!visited[i])

            BFS(G,i);

}

int main()

{

    ALGraph G;

    Init_ALGraph(G);

    printf("深度优先遍历结果:/n");

    DFSTraverse(G);

    printf("/n");

    printf("广度优先遍历结果:/n");

        BFSTraverse(G);

    printf("/n");

    return 0;

}

 

例子二:邻接矩阵表示图的深度遍历和广度遍历

#define MAX_VERTEX_NUM 20 //顶点个数

#include<iostream>

#include<string>

#include<queue> //队列头文件

using namespace std;

typedef int AdjMatrix;

typedef string VexType;

bool visited[MAX_VERTEX_NUM]; //标记是否采访过

typedef struct MGraph  //采用邻接矩阵作为图的存储结构

{

    VexType vertex[MAX_VERTEX_NUM];

    AdjMatrix arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

    int vexnum,arcnum;

}MGraph;

void Init_MGraph(MGraph &G)//初始化图

{

    int i,j,k;

    printf("请输入图的顶点数:");

    cin>>G.vexnum;

    printf("请输入图的边数:");

    cin>>G.arcnum;

    printf("请输入顶点的数值:");

    for(k=0;k<G.vexnum;k++)

        cin>>G.vertex[k];

    for(i=0;i<G.vexnum;i++)

        for(j=0;j<G.vexnum;j++)

            G.arcs[i][j]=0;  //初始化邻接矩阵

    printf("请输入相关联的边:/n");

    for(k=0;k<G.arcnum;k++)

    {

        cin>>i>>j;

        G.arcs[i-1][j-1]=1; //插入该边

        G.arcs[j-1][i-1]=1;

    }

}

void DFS(MGraph G,int i)//深入优先搜索

{

    visited[i]=true;//采访过

    cout<<G.vertex[i]<<" "; //输出

    for(int j=0;j<G.vexnum;j++)//遍历相关联的边

        if(G.arcs[i][j]&&!visited[j])

            DFS(G,j);

}

void DFSTraverse(MGraph G)

{

    memset(visited,false,sizeof(visited));//赋初值

    for(int i=0;i<G.vexnum;i++)

        if(!visited[i])//遍历各个顶点

            DFS(G,i);

}

void BFS(MGraph G,int i)//宽度优先搜索

{

    queue<int> q; //初始化队列

    q.push(i); //进队列

    visited[i]=true; //采访过

    cout<<G.vertex[i]<<" "; //输出

    while(!q.empty())

    {

        i=q.front();

        q.pop();

        for(int j=0;j<G.vexnum;j++)//遍历相关联的边

            if(G.arcs[i][j]&&!visited[j])

            {

                q.push(j);  //进队列

                visited[j]=true;//采访过

                cout<<G.vertex[j]<<" ";//输出

            }

    }

}

void BFSTraverse(MGraph G)

{

    memset(visited,false,sizeof(visited));//赋初值

    for(int i=0;i<G.vexnum;i++)//遍历各个顶点

        if(!visited[i])

            BFS(G,i);

}

int main()

{

    MGraph G;

    Init_MGraph(G);

    printf("深度优先遍历结果:/n");

    DFSTraverse(G);

    printf("/n");

    printf("广度优先遍历结果:/n");

    BFSTraverse(G);

    printf("/n");

    return 0;

}

 

备注:算法应该不会考,排序,查找也应该不会考。查找算法例子如下:

例子一:创建顺序表的二分查找(折半查找),返回查找值的位置

#include<iostream>

using namespace std;

int cmp(const void*b,const void*c){

  return *(int*)b-*(int*)c;

}

 

int binsearch(int *p,int elem,int n){

    int low=0,high=n-1,mid;

    while(low<=high){

        mid=(low+high)/2;

        if(p[mid]==elem)

            return mid+1;

        else if(p[mid]>elem)

                 high=mid-1;

             else

                 low=mid+1;//返回查找元素的位置

    }

    return -1;

}

 

int main(){

   int n,i;

   cin>>n;

   int *p=new int[n];

   for(i=0;i<=n-1;++i)

       cin>>p[i];

   qsort(p,n,sizeof(int),cmp);

   for(i=0;i<=n-1;++i)

       cout<<p[i]<<" ";

   cout<<endl;

   cout<<binsearch(p,6,n)<<endl;

   return 0;

}

例子二:顺序表的二分查找(折半查找),即bsearch() 的应用

#include<iostream>

using namespace std;

int cmp(const void*b,const void*c){

  return *(int*)b-*(int*)c;

}

 

int main(){

   int n,i;

   cin>>n;

   int *p=new int[n];

   for(i=0;i<=n-1;++i)

       cin>>p[i];

   qsort(p,n,sizeof(int),cmp);

   for(i=0;i<=n-1;++i)

       cout<<p[i]<<" ";

   cout<<endl;

   int e;

   cin>>e;

   int *q,*t=&e;

   q=(int*)bsearch(t,p,n,sizeof(int),cmp);

   cout<<*q<<endl;

   return 0;

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值