数据结构与算法程序集

*/ --------------------------------------------------------------------------------------
*/ 
出自: CSDN学生大本营http://student.csdn.net/
*/ 
作者: 斯之不远    E-mailsizhibuyuan@163.com    QQ1170927177
*/ 
时间: 2011-3-24  
*/ 
声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------

数据结构课程中写的学习例程,在此收集到一起。一般程序都不难也不大,并且所有例程均有较详细注释。中间有一个哈夫曼编码,程序较大,希望能给大家一点启示。以下所有程序均在VC++6.0开发环境中调试通过,运行正常。


数据结构与算法基本程序目录
一、      线性表及其操作
1
     尾插法建立一个单链表,并按顺序输出
2
     单链表的元素查找,按内容查找
3
     元素插入操作
4
     按内容元素删除操作
5
     按位置删除元素
6
     建立双向链表
7
     单链表就地逆置
8
     约瑟夫环问题
二、      栈及其操作
1
     建立堆栈
2
     进栈与出栈
3
     栈的应用,括号匹配
三、      队及其操作
1
     链队列的建立
2
     入队和出队
3
     循环队列建立
4
     循环队列的入队和出队操作
四、      串及其操作
1
     串的朴素匹配
五、      树(二叉树)及其操作
1
     二叉排序树
2
     哈夫曼编码
六、      排序
1
     冒泡排序
2
     直接选择排序法

一、线性表及其操作
//All copyright are preserved by cobby
/*
尾插法建立一个单链表,并按顺序输出 */
#define NULL 0            /* 宏定义 */
typedef struct node        /*
定义结点类型的数据结构 */
{
    char c;            /*
数据域,类型为字符型 */
    struct node *next;    /*
指针域,类型为本结构体类型 */
}*L;            /*
类型重定义,即 Node *L struct node 等价 */
main()
{
    L l,p,q;        /*
用指针类型定义三个结点类型的指针 */
    char ch;
    l=(L)malloc(sizeof(L));    /*
分配内存空间 */
    l->c='/0';            /*
为头结点的数据域赋值,值为空 */
    l->next=NULL;            /*
指明下一个结点目前不存在 */
    q=l;                /*q
为游动指针,链表结点的连结要用 */
    printf("Input a character:/n");
    scanf("%c",&ch);
    getchar();        //
此语句用来吸收键盘输入的回车符,没有其它含义
    while(ch!='!')            /*
输入 ! 表示输入结束 */
    {
        p=(L)malloc(sizeof(L));    /*
为新输入的数据分配内存空间 */
        p->c=ch;
        p->next=NULL;            /*
新输入的结点在链表的最后,即它的后面没有其它元素 */
        q->next=p;            /*q
用于将上一个元素链接至当前新元素 */
        q=p;                /*q
自己移到当前最后一个元素,以备继续链接所用 */
        scanf("%c",&ch);
        getchar();
    }
    q=l;                /*
输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q->next!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->next->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
}

//All copyright are preserved bycobby
/*
单链表的元素查找,按内容查找 */

#define NULL 0            /*
宏定义 */
typedef struct node        /*
定义结点类型的数据结构 */
{
    char c;            /*
数据域,类型为字符型 */
    struct node *next;    /*
指针域,类型为本结构体类型 */
}*L;            /*
类型重定义,即 Node *L struct node 等价 */
main()
{
    L l,p,q;        /*
用指针类型定义三个结点类型的指针 */
    char ch;
    int n;
    l=(L)malloc(sizeof(L));    /*
分配内存空间 */
    l->c='/0';            /*
为头结点的数据域赋值,值为空 */
    l->next=NULL;            /*
指明下一个结点目前不存在 */
    q=l;                /*q
为游动指针,链表结点的连结要用 */
    printf("Input a character:/n");
    scanf("%c",&ch);
    getchar();
    while(ch!='!')            /*
输入 ! 表示输入结束 */
    {
        p=(L)malloc(sizeof(L));    /*
为新输入的数据分配内存空间 */
        p->c=ch;
        p->next=NULL;            /*
新输入的结点在链表的最后,即它的后面没有其它元素 */
        q->next=p;            /*q
用于将上一个元素链接至当前新元素 */
        q=p;                /*q
自己移到当前最后一个元素,以备继续链接所用 */
        scanf("%c",&ch);
        getchar();
    }
    q=l;                /*
输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q->next!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->next->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
    /*-------- 以上为建立一个单链表 -------------*/

    printf("/nInput a character you wanna find/n");
    scanf("%c",&ch);
    printf("/nthe character you wanna find is %c/n",ch);
    q=l->next;        /*q
移至头结点的后一个元素,即实际第一个数据点 */
    n=1;    //
位置计数器
    while(q!=NULL)        /*
q 不为空,即该结点存在 */
    {
        if(q->c==ch)    /*
字符匹配 */
            printf("character found in position %d/n",n);
        q=q->next;    /*
移至下一个元素继续查找 */
        n++;
    }
}

//All copyright are preserved bycobby
/*
元素插入操作 */
#define NULL 0            /* 宏定义 */
typedef struct node        /*
定义结点类型的数据结构 */
{
    char c;            /*
数据域,类型为字符型 */
    struct node *next;    /*
指针域,类型为本结构体类型 */
}Node,*L;            /*
类型重定义,即 Node *L struct node 等价 */
main()
{
    L l,p,q;        /*
用指针类型定义三个结点类型的指针 */
    char ch;
    int pos,n;
    l=(L)malloc(sizeof(Node));    /*
分配内存空间 */
    l->c='/0';            /*
为头结点的数据域赋值,值为空 */
    l->next=NULL;            /*
指明下一个结点目前不存在 */
    q=l;                /*q
为游动指针,链表结点的连结要用 */
    printf("Input a character:/n");
    scanf("%c",&ch);
    getchar();
    while(ch!='!')            /*
输入 ! 表示输入结束 */
    {
        p=(L)malloc(sizeof(Node));    /*
为新输入的数据分配内存空间 */
        p->c=ch;
        p->next=NULL;            /*
新输入的结点在链表的最后,即它的后面没有其它元素 */
        q->next=p;            /*q
用于将上一个元素链接至当前新元素 */
        q=p;                /*q
自己移到当前最后一个元素,以备继续链接所用 */
        scanf("%c",&ch);
        getchar();
    }
    q=l;                /*
输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q->next!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->next->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
    /* 以上为建立一个单链表 */
    printf("Input the character and its position, such as s,3/n/n");
    scanf("%c,%d",&ch,&pos);
    q=l;
    n=1;
    while(n!=pos&&q->next!=NULL)        /*
未找到插入位置,且后面还有元素 */
    {
        q=q->next;
        n++;
    }
    /*
退出循环后,要么找到插入位置,要么表已到最后,输入的插入位置过大 */
    if(n<pos)    /* 表已读完,仍未找到插入位置 */
        printf("/n/nincorrect position, insert failed/n/n");
    else        /*
找到插入位置 */
    {
        /*
将进行插入操作 */
        p=(L)malloc(sizeof(Node));    /*
给新输入的数据分配内存空间 */
        p->c=ch;
        p->next=q->next;
        q->next=p;
    }
    /* 操作完成,然后输出新表 */
    
    q=l;                /*
输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q->next!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->next->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
}

//All copyright are preserved bycobby
/*
按内容元素删除操作 */
#include<malloc.h>
#include<stdio.h>
#define NULL 0            /* 宏定义 */
typedef struct node        /*
定义结点类型的数据结构 */
{
    char c;            /*
数据域,类型为字符型 */
    struct node *next;    /*
指针域,类型为本结构体类型 */
}Node,*L;            /*
类型重定义,即 Node *L struct node 等价 */
main()
{
    L l,p,q;        /*
用指针类型定义三个结点类型的指针 */
    char ch;
    int n;
    l=(L)malloc(sizeof(Node));    /*
分配内存空间 */
    l->c='/0';            /*
为头结点的数据域赋值,值为空 */
    l->next=NULL;            /*
指明下一个结点目前不存在 */
    q=l;                /*q
为游动指针,链表结点的连结要用 */
    printf("Input a character:/n");
    scanf("%c",&ch);
    getchar();
    while(ch!='!')            /*
输入 ! 表示输入结束 */
    {
        p=(L)malloc(sizeof(Node));    /*
为新输入的数据分配内存空间 */
        p->c=ch;
        p->next=NULL;            /*
新输入的结点在链表的最后,即它的后面没有其它元素 */
        q->next=p;            /*q
用于将上一个元素链接至当前新元素 */
        q=p;                /*q
自己移到当前最后一个元素,以备继续链接所用 */
        scanf("%c",&ch);
        getchar();
    }
    q=l;                /*
输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q->next!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->next->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
    /* 以上为建立单链表 */
    printf("input the character you wanna delete/n/n");
    scanf("%c",&ch);
    printf("the element you wanna delete is %c/n/n",ch);
    q=l->next;
    p=l;
    n=1;
    while(q!=NULL&&q->c!=ch)
    {
        p=q;
        q=q->next;
        n++;
    }
    /*
退出循环时可能找到指定元素,也可能表读完,需要进一步判断 */
    
    if(q==NULL)
        printf("element not found, delete failed/n/n");
    else
        p->next=q->next;
    q=l->next;                /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
}
//All copyright are preserved bycobby
/*
按位置删除元素 */
#define NULL 0            /* 宏定义 */
typedef struct node        /*
定义结点类型的数据结构 */
{
    char c;            /*
数据域,类型为字符型 */
    struct node *next;    /*
指针域,类型为本结构体类型 */
}Node,*L;            /*
类型重定义,即 Node *L struct node 等价 */
main()
{
    L l,p,q;        /*
用指针类型定义三个结点类型的指针 */
    char ch;
    int pos,n;
    l=(L)malloc(sizeof(Node));    /*
分配内存空间 */
    l->c='/0';            /*
为头结点的数据域赋值,值为空 */
    l->next=NULL;            /*
指明下一个结点目前不存在 */
    q=l;                /*q
为游动指针,链表结点的连结要用 */
    printf("Input a character:/n");
    scanf("%c",&ch);
    getchar();
    while(ch!='!')            /*
输入 ! 表示输入结束 */
    {
        p=(L)malloc(sizeof(Node));    /*
为新输入的数据分配内存空间 */
        p->c=ch;
        p->next=NULL;            /*
新输入的结点在链表的最后,即它的后面没有其它元素 */
        q->next=p;            /*q
用于将上一个元素链接至当前新元素 */
        q=p;                /*q
自己移到当前最后一个元素,以备继续链接所用 */
        scanf("%c",&ch);
        getchar();
    }
    q=l;                /*
输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q->next!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->next->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
    /* 以上为建立单链表 */
    printf("Input the position/n");
    scanf("%d",&pos);
    p=l;
    n=1;
    while(p->next!=NULL&&n!=pos)
    {
        p=p->next;
        n++;
    }
    /*
退出循环后,可能找到删除的元素位置,可能表读完,需要进一步判断 */
    if(n==pos)    /*
删除位置找到,删除该位置上的元素 */
    {
        p->next=p->next->next;
        //free(p);
    }
    else
        printf("incorrect position, delete failed/n");
    q=l;                /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q->next!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->next->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
}
// 建立双向链表
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define NULL 0
typedef struct dlnode
{
    char ch;
    struct dlnode *pri,*next;
}dnode,*dl;
main()
{
    dl l,p,q;
    char c;
    l=(dl)malloc(sizeof(dnode));
    l->ch='/0';
    l->next=NULL;
    l->pri=NULL;
    q=l;
    printf(" 输入字符建立双向链表 /n");
    scanf("%c",&c);
    getchar();
    
    while(c!='!')
    {
        p=(dl)malloc(sizeof(dnode));
        p->ch=c;
        p->pri=q;
        p->next=NULL;
        q->next=p;
        q=p;
        scanf("%c",&c);
        getchar();
    }
    q=l;
    while(q->next!=NULL)
    {
        q=q->next;
        printf("%c-->",q->ch);
    }
    
    printf("/n");
    while(q->pri!=NULL)
    {
        printf("%c-->",q->ch);
        q=q->pri;
    }
    printf("/n");
}
// 单链表就地逆置
#define NULL 0            /* 宏定义 */
typedef struct node        /*
定义结点类型的数据结构 */
{
    char c;            /*
数据域,类型为字符型 */
    struct node *next;    /*
指针域,类型为本结构体类型 */
}Node,*L;            /*
类型重定义,即 Node *L struct node 等价 */
main()
{
    L l,p,q,r;        /*
用指针类型定义三个结点类型的指针 */
    char ch;
    l=(L)malloc(sizeof(Node));    /*
分配内存空间 */
    l->c='/0';            /*
为头结点的数据域赋值,值为空 */
    l->next=NULL;            /*
指明下一个结点目前不存在 */
    q=l;                /*q
为游动指针,链表结点的连结要用 */
    printf("Input a character:/n");
    scanf("%c",&ch);
    getchar();
    while(ch!='!')            /*
输入 ! 表示输入结束 */
    {
        p=(L)malloc(sizeof(Node));    /*
为新输入的数据分配内存空间 */
        p->c=ch;
        p->next=NULL;            /*
新输入的结点在链表的最后,即它的后面没有其它元素 */
        q->next=p;            /*q
用于将上一个元素链接至当前新元素 */
        q=p;                /*q
自己移到当前最后一个元素,以备继续链接所用 */
        scanf("%c",&ch);
        getchar();
    }
    q=l;                /*
输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q->next!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->next->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
    printf("/n");
    // 以上完成了单链表的创建
    q=l->next;
    p=q->next;
    r=p->next;
    q->next=NULL;
    while(r!=NULL)
    {
        p->next=q;
        q=p;
        p=r;
        if(r->next!=NULL)    //r
后面还有结点,则逆置继续
            r=r->next;
        else
            break;
    }
    r->next=q;
    l->next=r;        //
头结点指向最后一个结点
    q=l;                /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
    while(q->next!=NULL)        /*
q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
    {
        printf("%c-->",q->next->c);    /*q->next->c
表示 q 所指向的下一个元素的数据 */
        q=q->next;            /*
完成该元素的输出后, q 移至下一个元素重复输出操作 */
    }
    printf("/n");
}

//
约瑟夫环问题
#include<stdio.h>
#include<malloc.h>
typedef struct lnode
{
    int num;
    struct lnode *next;
}node,*L;
main()
{
    int amount,start,circle,n,c;
    L p,l,q;
    printf(" 一共有几个人围成一圈? /n");
    scanf("%d",&amount);
    getchar();
    printf("
从第几个开始计数? /n");
    scanf("%d",&start);
    getchar();
    printf("
每几人一次循环? /n");
    scanf("%d",&circle);
    getchar();
    l=(L)malloc(sizeof(node));        // 头结点
    l->next=NULL;
    l->num=0;
    q=l;
    n=0;
    while(n++<amount)
    {
        p=(L)malloc(sizeof(node));
        p->next=NULL;
        p->num=n;
        q->next=p;
        q=p;
    }
    q->next=l->next;        //
形成循环链表
    // 以上完成了单向循环链表的建立
    p=l->next;
    q=l;
    n=1;
    while(n++<start)
    {
        p=p->next;
        q=q->next;
    }
    //
退出循环时 p,q 分别位于指定位置
    // 接下去进行周期性结点删除,直到链表只余一个结点为止
    n=1;        //n
计算被删除的结点的数量,当 n=amount-1 时删除结束
    while(n++<amount)
    {
        c=1;    //c
作为循环临时变量
        while(c++<circle)
        {
            p=p->next;
            q=q->next;
        }
        //
删除当前 p 指向的结点
        printf("
删除结点 %d/t",p->num);
        q->next=p->next;
        p=p->next;
    }
    printf("/n
最后剩下 %d/n",p->num);
}
二、栈及其操作
//All copyright are preserved bycobby
/*
建立堆栈 */
#include<stdio.h>
#include<malloc.h>
#define NULL 0
typedef struct node
{
    char ch;
    struct node *next;
}Snode,*stack;
main()
{
    stack s,top,p;
    char ch;
    
    s=(stack)malloc(sizeof(Snode));
    s->ch='/0';
    s->next=NULL;        /*
建立栈底指针 */
    top=s;
    scanf("%c",&ch);
    getchar();
    
    while(ch!='!')
    {
        p=(stack)malloc(sizeof(Snode));
        p->ch=ch;
        p->next=top;
        top=p;
        scanf("%c",&ch);
        getchar();
    }
    while(top->next!=NULL)
    {
        printf("%c-->",top->ch);
        top=top->next;
    }
    printf("/n");
}

//All copyright are preserved bycobby
/*
进栈与出栈 */
#include<stdio.h>
#include<malloc.h>
#define NULL 0
typedef struct node
{
    char ch;
    struct node *next;
}Snode,*stack;
main()
{
    stack s,top,p;
    char ch;
    int choice;
    
    s=(stack)malloc(sizeof(Snode));
    s->ch='!';
    s->next=NULL;        /*
建立栈底指针 */
    top=s;
    scanf("%c",&ch);
    getchar();
    
    while(ch!='!')
    {
        p=(stack)malloc(sizeof(Snode));
        p->ch=ch;
        p->next=top;
        top=p;
        scanf("%c",&ch);
        getchar();
    }
    while(p->next!=NULL)    // 此处 p 可用 top 代替
    {
        printf("%c-->",p->ch);
        p=p->next;
    }
    printf("/n");
    /* 以上建立了一个堆栈 */
    printf(" 进栈或出栈?输入 “1” 为进栈,输入 “2” 为出栈,其它则退出程序 /n");
    scanf("%d",&choice);
    getchar();
    while(choice==1||choice==2)    //
若不是输入 1 2 ,则不做任何操作
    {
        if(choice==1)
        {
            /*
进栈 */
            printf("/n
输入要入栈的元素 /n");
            scanf("%c",&ch);
            getchar();
            
            p=(stack)malloc(sizeof(Snode));
            p->ch=ch;
            p->next=top;
            top=p;
        }
        else if(choice==2)
        {
            if(top->next!=NULL)
                top=top->next;
            else
            {
                printf("
栈已清空 /n");
                exit();
            }
            /*
出栈 */
        }
        //printf("%c-->",top->ch);
        p=top;
        while(p->next!=NULL)
        {
            printf("%c-->",p->ch);
            p=p->next;
        }
        printf("/n");
        printf("
进栈或出栈?输入 “1” 为进栈,输入 “2” 为出栈,其它则退出程序 /n");
        scanf("%d",&choice);
        getchar();
    }
}

//All copyright are preserved bycobby
//
栈的应用,括号匹配
#include<stdio.h>
#include<malloc.h>
#define NULL 0
typedef struct node
{
    char ch;
    struct node *next;
}snode,*stack;
main()
{
    stack s,top,p;
    char *string,ch[100]="";
    s=(stack)malloc(sizeof(snode));        // 建立栈底元素
    s->ch='/0';
    s->next=NULL;
    top=s;
    printf(" 输入一个含括号的四则运算表达式: /n");
    scanf("%s",ch);
    string=ch;
    while(*string!='/0')
    {
        if(*string=='('||*string=='['||*string=='{')    //
遇到左括号,入栈
        {
            p=(stack)malloc(sizeof(snode));
            p->ch=*string;
            p->next=top;
            top=p;
        }
        else if(*string==')'||*string==']'||*string=='}')    //
遇到右括号
        {
            if(*string==')')
                if(top->ch=='(')    //
括号匹配
                    top=top->next;
                else
                {
                    printf("
小括号不匹配 ");
                    exit(0);
                }
            else if(*string==']')
                if(top->ch=='[')    //
括号匹配
                    top=top->next;
                else
                {
                    printf("
中括号不匹配 ");
                    exit(0);
                }
            else
                if(top->ch=='{')    //
括号匹配
                    top=top->next;
                else
                {
                    printf("
大括号不匹配 ");
                    exit(0);
                }
        }
        string++;
    }
    if(top->ch!='/0')
        printf("
多出左括号 %c/n",top->ch);
    
}
  三、队及其操作
//All copyright are preserved bycobby
//
链队列的建立
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define NULL 0
typedef struct node            // 队列结点的基本数据结构,即队列中每个结点的类型
{
    char c;
    struct node *next;
}qnode,*basic_node;
typedef struct            // 队列实际上由头、尾两个结点指针构成,即头指针和尾指针唯一确定时,队列也被唯一确定
{
    qnode *head;
    qnode *rear;
}queue,*Q;
main()
{
    Q q;    //
定义队列,结构体变量 q 中含有头指针 head 和尾指针 rear ,所以 q 是一个完整的队列(只不过队列为空)
            //
事实上,任何由 Q 定义的结构体变量都是一个独立完整的队列
    basic_node p,l;        //basic_node
是基本结点类型,即是独立的结点,它是组成队列的基本元素。
    //
基本结点 p,l 和队列 q 的关系可由下图表示:
    //  (q->head)--->p--->l--->p--->l--->……--->p--->l--->(q->rear)
    char ch;
    q=(Q)malloc(sizeof(queue));
    q->head=NULL;    //
初始化时队列为空
    q->rear=NULL;
    printf(" 输入队列元素 :/n");
    scanf("%c",&ch);
    getchar();
    
    while(ch!='!')
    {
        p=(qnode*)malloc(sizeof(qnode));
        p->c=ch;
        p->next=NULL;        //
新来的元素一定在队列的最后,它的后面没有其它元素
        if(q->head==NULL)
        {
            q->head=p;        //
第一个元素入队时,队头指针指向它
            l=q->head;        //l
指向第一个元素
        }
        l->next=p;            //
使前一个元素指向当前入队的新元素
        l=p;                //l
移动到当前新元素,以备用下次入队操作
        q->rear=p;            //
修改队尾指针,使其总是指向当前最后一个队列元素
        scanf("%c",&ch);
        getchar();
    }
    l=q->head;
    while(l!=NULL)
    {
        printf("%c<--",l->c);
        l=l->next;
    }
    printf("/n");
    printf("
头指针指向元素为 %c/t 尾指针指向元素为 %c/n",q->head->c,q->rear->c );
}

//All copyright are preserved bycobby
// 入队和出队
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define NULL 0
typedef struct node            // 队列结点的基本数据结构,即队列中每个结点的类型
{
    char c;
    struct node *next;
}qnode,*basic_node;
typedef struct            // 队列实际上由头、尾两个结点指针构成,即头指针和尾指针唯一确定时,队列也被唯一确定
{
    qnode *head;
    qnode *rear;
}queue,*Q;
main()
{
    Q q;    //
定义队列,结构体变量 q 中含有头指针 head 和尾指针 rear ,所以 q 是一个完整的队列(只不过队列为空)
            //
事实上,任何由 Q 定义的结构体变量都是一个独立完整的队列
    basic_node p,l;        //basic_node
是基本结点类型,即是独立的结点,它是组成队列的基本元素。
    //
基本结点 p,l 和队列 q 的关系可由下图表示:
    //  (q->head)--->p--->l--->p--->l--->……--->p--->l--->(q->rear)
    char ch;
    int choice;
    q=(Q)malloc(sizeof(queue));
    q->head=NULL;    //
初始化时队列为空
    q->rear=NULL;
    printf(" 输入队列元素 :/n");
    scanf("%c",&ch);
    getchar();
    
    while(ch!='!')
    {
        p=(qnode*)malloc(sizeof(qnode));
        p->c=ch;
        p->next=NULL;        //
新来的元素一定在队列的最后,它的后面没有其它元素
        if(q->head==NULL)
        {
            q->head=p;        //
第一个元素入队时,队头指针指向它
            l=q->head;        //l
指向第一个元素
        }
        l->next=p;            //
使前一个元素指向当前入队的新元素
        l=p;                //l
移动到当前新元素,以备用下次入队操作
        q->rear=p;            //
修改队尾指针,使其总是指向当前最后一个队列元素
        scanf("%c",&ch);
        getchar();
    }
    l=q->head;
    while(l!=NULL)
    {
        printf("%c<--",l->c);
        l=l->next;
    }
    printf("/n");
    printf("
头指针指向元素为 %c/t 尾指针指向元素为 %c/n",q->head->c,q->rear->c );

    //
以上建立了一个队列
    printf(" 输入 1 进行入队,输入 2 进行出队 :/n");
    scanf("%d",&choice);
    getchar();
    if(choice==1)
    {
        printf("/n
输入要入队的元素 :/n");
        scanf("%c",&ch);
        getchar();
        p=(qnode*)malloc(sizeof(qnode));    //
给新入队的元素分配内存空间
        p->c=ch;
        p->next=NULL;        //
新元素为最后一个元素
        q->rear->next=p;    //
原来最后一个元素指向新入队的元素
        q->rear=p;            //
修改队尾指针,使其指向当前最后一个元素
    }
    else if(choice==2)
        q->head=q->head->next;
    else
        exit(0);
    l=q->head;
    while(l!=NULL)
    {
        printf("%c<--",l->c);
        l=l->next;
    }
    printf("/n");
    printf("
头指针指向元素为 %c/t 尾指针指向元素为 %c/n",q->head->c,q->rear->c );
}

//All copyright are preserved bycobby
//
循环队列建立
#include<stdio.h>
#include<malloc.h>
#define MAX 8
typedef struct
{
    char c[MAX];    //
循环队列是顺序队列的一种,它的核心就是一个数组
    int front;        //
整形变量,作为头指针用
    int rear;        //
整形变量,作为尾指针用
}queue;
main()
{
    queue *q;
    char ch;
    int i;
    
    q=(queue*)malloc(sizeof(queue));    //
生成一个空循环队列
    for(i=0;i<MAX;i++)
        q->c[i]='/0';
    q->front=0;
    q->rear=0;
    printf(" 输入要入队的元素 :/n");
    scanf("%c",&ch);
    getchar();
    while(ch!='!')
    {
        if((q->rear+1)%MAX==q->front)    //
若队列已满
        {
            printf("
队列已满,无法入队 /n");
            break;
        }
        else
        {
            q->c[q->rear]=ch;    //rear
指向当前可入队的数组元素位置
        
            q->rear=(q->rear+1)%MAX;            //
修改尾指针,向后移动一个位置
            //
注意,不能简单使用 q->rear++ ,不然会导致队列溢出
        }
        scanf("%c",&ch);
        getchar();
    }
    for(i=q->front;i<q->rear;i=(i+1)%MAX)        // 能够用 for 循环,说明了顺序队列和链式队列的区别
        printf("%c<--",q->c[i]);
    printf("/n");
}

//All copyright are preserved bycobby
//
循环队列的入队和出队操作
#include<stdio.h>
#include<malloc.h>
#define MAX 8
typedef structd
{
    char c[MAX];    //
循环队列是顺序队列的一种,它的核心就是一个数组
    int front;        //
整形变量,作为头指针用
    int rear;        //
整形变量,作为尾指针用
}queue;
main()
{
    queue *q;
    char ch;
    int i,choice;
    
    q=(queue*)malloc(sizeof(queue));    //
生成一个空循环队列
    for(i=0;i<MAX;i++)
        q->c[i]='/0';
    q->front=0;
    q->rear=0;
    printf(" 输入要入队的元素 :/n");
    scanf("%c",&ch);
    getchar();
    while(ch!='!')
    {
        if((q->rear+1)%MAX==q->front)    //
若队列已满
        {
            printf("
队列已满,无法入队 /n");
            break;
        }
        else
        {
            q->c[q->rear]=ch;    //rear
指向当前可入队的数组元素位置
        
            q->rear=(q->rear+1)%MAX;            //
修改尾指针,向后移动一个位置
            //
注意,不能简单使用 q->rear++ ,不然会导致队列溢出
        }
        scanf("%c",&ch);
        getchar();
    }
    printf(" 头指针指向元素为 %d/t 尾指针指向元素为 %d/n",q->front,q->rear);
    for(i=q->front;i<q->rear;i=(i+1)%MAX)        // 能够用 for 循环,说明了顺序队列和链式队列的区别
        printf("%c-->",q->c[i]);
    printf("/n");
    // 以上建立了一个循环队列
    printf("
输入 1 入队,输入 2 出队 :/n");
    scanf("%d",&choice);
    getchar();
    while(choice==1||choice==2)
    {
        if(choice==1)
        {
            printf("
输入要入队的元素 /n");
            scanf("%c",&ch);
            getchar();
            if((q->rear+1)%MAX==q->front)    //
若队列已满
            {
                printf("
队列已满,无法入队 /n");
                break;
            }
            else
            {
                q->c[q->rear]=ch;    //rear
指向当前可入队的数组元素位置
                q->rear=(q->rear+1)%MAX;            //
修改尾指针,向后移动一个位置
                //
注意,不能简单使用 q->rear++ ,不然会导致队列溢出
            }
        }
        else if(choice==2)
        {
            if((q->front+1)%MAX!=q->rear)    //
队非空
            {
                q->c[q->front]='/0';    //
删除元素
                q->front=(q->front+1)%MAX;    //
修改队头指针
            }
            else
            {
                printf("
队已清空 /n");
                break;
            }
        }
        if(q->rear>q->front)    // 尾指针在头指针的右边
        {
            for(i=q->front;i<q->rear;i=(i+1)%MAX)        //
能够用 for 循环,说明了顺序队列和链式队列的区别
                printf("%c<--",q->c[i]);
            printf("/n");
        }
        else        //
尾指针在头指针的左边
        {
            for(i=q->front;i<(q->rear+MAX);i++)        //
能够用 for 循环,说明了顺序队列和链式队列的区别
                printf("%c<--",q->c[i%MAX]);
            printf("/n");
        }
        printf("
头指针指向元素为 %d/t 尾指针指向元素为 %d/n",q->front,q->rear);
        printf(" 输入 1 入队,输入 2 出队 :/n");
        scanf("%d",&choice);
        getchar();
    }
}
四、串及其操作
//
串的朴素匹配
#include<stdio.h>
main()
{
    char str1[100],str2[100],*p;
    int i=0,j=0,len_str1=0,len_str2=0,num=0;
    printf("
输入母串 :/n");
    scanf("%s",str1);
    getchar();
    printf("% 输入子串 :/n");
    scanf("%s",str2);
    getchar();
    p=str1;
    while(*p!='/0')        //
获取母串长度
    {
        len_str1++;
        p++;
    }
    p=str2;        // 获取子串长度
    while(*p!='/0')
    {
        len_str2++;
        p++;
    }
    
    for(i=0;i<len_str1;i++)    //i
为母串下标
    {
        for(j=0;j<len_str2;j++)        //j
为子串下标
        {
            num++;
            if(str1[i+j]!=str2[j])
                break;        //
若当前字符不匹配,则指针向母串下一个字符移动
        }
        if(j==len_str2)
        {
            printf("
子串在母串中的位置为 %d/n",i+1);
            //break;        //
若子串在母串中多次出现,则全部找到其位置。若恢复 break 语句则只找出最前的一个匹配子串
        }
    }        
    printf("
母串长度为 %d, 子串长度为 %d/n 核心语句执行次数为 %d/n",len_str1,len_str2,num);
}
五、树(二叉树)及其操作
//
二叉排序树
#include<stdio.h>
#include<stdlib.h>
typedef struct tnode
{
    int num;
    struct tnode *Lchild,*Rchild;
}Tnode,*Btree;
typedef struct snode
{
    int num;
    Btree r;
    struct snode *next;
}Snode,*stack;
Btree root;
void describe_tree()    // 交互式显示哈夫曼树
{
    Btree t;
    stack s,top,temp;
    int choice;
    s=(stack)malloc(sizeof(Snode));
    s->num=0;
    s->next=NULL;
    s->r=NULL;
    top=s;
    
    t=root;//t
指向哈夫曼树的根结点
    temp=(stack)malloc(sizeof(Snode));    // 分配新栈结点     
    temp->num=t->num;
    temp->next=top;        //
结点入栈
    temp->r=t;    //
将当前二叉树结点指针给栈顶结点
    top=temp;        //
修改栈顶指针
    printf(" 输入 1 往左子树,输入 2 往右子树,输入 3 返回父结点,其它输入退出程序 /n");
    scanf("%d",&choice);
    getchar();
    
    while(choice==1||choice==2||choice==3)
    {
        if(choice==1)        //
往左子树
        {
            if(t->Lchild!=NULL)
            {
                t=t->Lchild;
                temp=(stack)malloc(sizeof(Snode));    //
分配新栈结点
                //
新结点入栈     
                temp->num=t->num;
                temp->next=top;        //
结点入栈
                temp->r=t;    //
将当前二叉树结点指针给栈顶结点
                top=temp;        //
修改栈顶指针
                printf("
值为 %d/n",t->num);
            }
            else    //
左子树不存在,当前结点已经是叶子结点
                printf("
无左孩子! /n");    
        }
        else if(choice==2)    //
往右子树
        {
            if(t->Rchild!=NULL)
            {
                t=t->Rchild;
                temp=(stack)malloc(sizeof(Snode));    //
分配新栈结点
                //
新结点入栈
                temp->num=t->num;
                temp->next=top;        //
结点入栈
                temp->r=t;    //
将当前二叉树结点指针给栈顶结点
                top=temp;        //
修改栈顶指针
                printf("
值为 %d/n",t->num);
            }
            else    //
右子树不存在,当前结点已经是叶子结点
                printf("
无右孩子! /n");
        }
        else if(choice==3)    //
返回父结点
        {
            if(top->next!=s)    //
栈非空
            {
                top=top->next;
                t=top->r;
                printf("
值为 %d/n",t->num);
            }
            else
                printf("
已经在根结点了! /n");
        }
        scanf("%d",&choice);
        getchar();
    }
}
void inorder(Btree r)        // 中序递归遍历
{
    if(r!=NULL)
    {
        inorder(r->Lchild);
        printf(" %d <",r->num);
        inorder(r->Rchild);
    }
}
main()
{
    int array[100],n=0,i,choice;
    Btree p,q;
    for(i=0;i<100;i++)
        array[i]=0;
    printf(" 输入若干个整数 , 结束用 /"0/" 表示 /n");
    scanf("%d",&array[n++]);
    getchar();
    while(array[n-1]!=0)
        scanf("%d",&array[n++]);
    n=0;
    if(array[n]!=0)
    {
        root=(Btree)malloc(sizeof(Tnode));        //
建立二叉排序树的根结点
        root->num=array[n];
        root->Lchild=NULL;
        root->Rchild=NULL;
        n++;
    }
    else
        exit(0);
    while(array[n]!=0)
    {
        p=(Btree)malloc(sizeof(Tnode));        //
依次给每个整数分配结点
        p->num=array[n];
        p->Lchild=NULL;
        p->Rchild=NULL;
        // 分配完结点后,要插入到二叉树中合适的位置
        q=root;        //q
初始化到根结点
        while(q!=NULL)
        {
            if(q->num<p->num)    //
若新结点的值大于根结点的值,则往右子树
            {
                if(q->Rchild!=NULL)        //
当前结点有右孩子,则指针移向右孩子继续比较
                    q=q->Rchild;
                else        //
当前结点没有右孩子,则新结点为当前结点的右孩子
                {
                    q->Rchild=p;
                    break;
                }
            }
            else
            {
                if(q->Lchild!=NULL)        //
当前结点有左孩子,则指针移向左孩子继续比较
                    q=q->Lchild;
                else        //
当前结点没有左孩子,则新结点为当前结点的左孩子
                {
                    q->Lchild=p;
                    break;
                }
            }
        }
        n++;
    }
    
    
    //
建立二叉排序树完毕
    //
对其进行中序遍历
    
    printf("/n
哈夫曼树构造完成,是否查看哈夫曼树,输入 1 查看,其它输入跳过 ");
    scanf("%d",&choice);
    getchar();
    if(choice==1)
        describe_tree();
    
    inorder(root);
    printf("/n");
}
哈夫曼算法程序太大,一个贴放不下,下面两个贴均为哈夫曼编码程序 .

//2005/4/28
//All Copyright Are Reserved By cobby
//
哈夫曼编码
#include<stdio.h>
#include<malloc.h>
#include<math.h>
#define NULL 0
typedef struct huff_code_node    // 存储编码的链表
{
    char ch;    //
编码对应的字符
    char code[100];        //
字符对应的哈夫曼码
    struct huff_code_node *next;    
}hnode,*huff;
typedef struct tree_Node    // 二叉树结点
{
    char ch;    //
字符内容
    int amount;    //
字符在字符串中出现的次数
    struct tree_Node *left,*right;    //
指向左子树与右子树
}tnode,*bt;
typedef struct list_node        // 链表结点
{
    char ch;    //
存储字符串中的字符
    int amount;    //
字符在字符串中出现的次数
    tnode *son;    //
链表结点带有二叉子树的根结点指针
    struct list_node *next;    //
指向链表中下一个结点
}Node,*L;
typedef struct stack_node
{
    char ch;    //
存储字符
    int amount;        //
出现次数
    bt son;        //
指向二叉树的某结点
    struct stack_node *next;
}snode,*stack;

char t[200],*str,*c;    //
用于存储和处理输入的字符串
bt root=NULL;        //
哈夫曼树
L l,p,q,new_node;    //
链表结点
huff hlist;        //
计算得到的编码表
int char_num;    //
输入的不同字符数量
int char_amount;    //
输入的所有字符数量
int code_sum;        //
哈夫曼编码总长

void initial()        //
初始化操作
{
    l=(Node*)malloc(sizeof(Node));        //
建立空链表
    l->ch='/0';
    l->amount=0;
    l->son=NULL;
    l->next=NULL;
    str=t;    // 将字符串指针指向字符串的第一个位置
    //
键盘输入字符串
    printf("
输入字符串进行哈夫曼编码 :/n");
    scanf("%s",str);
    getchar();    
}
void pull_in_list()
{
    int exist;    //
表示当前字符是否存在于链表中, 0 为不存在, 1 为已存在
    int n;    //
计算输入不同字符的数量,计算后赋值给全局变量 char_num
    int m;    //
计算输入所有字符的数量,计算后赋值给全局变量 char_amount
    
    c=str;    //c
指向第一个字符
    
    while(*c!='/0')        //
若字符串未读完
    {
        exist=0;
        p=l;    //p
指向链表头结点
        //
寻找该字符是否已经在链表中
        while(p->next!=NULL)    //
若链表非空
        {
            p=p->next;
            if(p->ch==*c)    //
若当前字符已经在链表中
            {
                exist=1;
                p->amount++;    //
字符出现次数加 1
                break;
            }
        }
        if(exist==0)    // 若当前字符不存在于链表中,则分配一个结点入表
        {
            new_node=(Node*)malloc(sizeof(Node));
            new_node->ch=*c;
            new_node->amount=1;
            new_node->next=NULL;
            new_node->son=NULL;
            p->next=new_node;
            p=new_node;
        }
        c++;    //
读下一个字符
    }
    printf(" 统计结果 :/n");
    p=l;
    n=0;
    m=0;
    while(p->next!=NULL)
    {
        n++;
        p=p->next;
        m+=p->amount;
        printf("%c——%d/n",p->ch,p->amount);
    }
    char_num=n;
    char_amount=m;
    printf("
一共有 %d 种字符输入,字符总数 %d/n",char_num,char_amount);
}
int list_element_amount()        // 计算链表中结点的数量(不包括头结点)
{
    L temp;        //
定义临时指针
    int n=0;        //
结点数量
    temp=l;
    while(temp->next!=NULL)    //
后面还有结点
    {
        n++;
        temp=temp->next;
    }
    return n;
}
bt create()    // 建立最优二叉树
{
    //=========================================
    //
这些变量用于寻找最小结点
    L min1_pos,min2_pos,t,min_pri;
    bt min1_son,min2_son;
    int min1,min2;
    char min1_c,min2_c;
    //=========================================
    //=========================================
    //
这些变量用于构造二叉子树
    bt left,right,root;
    //==========================================
    //==========================================
    //
这些变量用于将二叉子树信息插入链表
    L made,temp_p;
    //============================================
    while(list_element_amount()>=2)    // 若表中还有两个或以上结点,则归并继续
    {
        //
选择次数值最小的两个结点
        //============================================================================
        //
先寻找第一个小结点
        t=l->next;
        min1=t->amount;        //
将第一个结点的次数值赋给 min1
        min1_pos=t;            //
将第一个结点的位置指针赋给 min1_pos
        min1_c=t->ch;        //
将第一个结点的字符赋值给 min1_c
        min1_son=t->son;    //
将第一个结点的二叉指针赋值给 min1_son
        min_pri=l;            //min_pri
始终指向最小结点的前驱,以方便删除最小结点
        while(t->next!=NULL)
        {
            t=t->next;
            if(min1>t->amount)    //
发现更小的结点
            {
                min1=t->amount;        //
将当前结点的次数值赋给 min1
                min1_pos=t;            //
将当前结点的位置指针赋给 min1_pos
                min1_c=t->ch;        //
将当前结点的字符赋值给 min1_c
                min1_son=t->son;    //
将当前结点的二叉指针赋值给 min1_son
            }
        }//
退出本循环时,最小结点的信息找出,将该结点删除
        min_pri=l;
        while(min_pri->next!=min1_pos)
            min_pri=min_pri->next;
        //
退出循环时 min_pri 指向 min1_pos 的前驱
        min_pri->next=min1_pos->next;        //
删除结点 min1_pos
        //
寻找第一个小结点完成
        //=================================================================
        //=================================================================
        //
先寻找第二个小结点
        t=l->next;
        min2=t->amount;        //
将第二个结点的次数值赋给 min2
        min2_pos=t;            //
将第二个结点的位置指针赋给 min2_pos
        min2_c=t->ch;
        min2_son=t->son;
        min_pri=l;        //min_pri
始终指向最小结点的前驱,以方便删除最小结点
        while(t->next!=NULL)
        {
            t=t->next;
            if(min2>t->amount)    //
发现更小的结点
            {
                min2=t->amount;        //
将当前结点的次数值赋给 min2
                min2_pos=t;            //
将当前结点的位置指针赋给 min2_pos
                min2_c=t->ch;
                min2_son=t->son;
            }
        }//
退出本循环时,最小结点的信息找出,将该结点删除
        min_pri=l;
        while(min_pri->next!=min2_pos)
            min_pri=min_pri->next;
        //
退出循环时 min_pri 指向 min1_pos 的前驱
        min_pri->next=min2_pos->next;        //
删除结点 min2_pos
        //
寻找第二个小结点完成
        //=================================================================

        //==================================================================
        //
两个最小结点找到,由这对结点级成一个二叉子树,将根结点插入链表中
        if(min1_son==NULL)    //
该结点无二叉子树指针,则须新分配一个二叉树结点
        {
            left=(bt)malloc(sizeof(tnode));        //
产生左孩子
            left->amount=min1;        //
次数值复制
            left->ch=min1_c;        //
字符复制
            left->left=NULL;
            left->right=NULL;
        }
        else    //
该结点为计算产生的结点,它已指向一个二叉子树
            left=min1_son;    //left
直接指向已经生成的二叉子树的根结点
        if(min2_son==NULL)    // 该结点无二叉子树指针,则须新分配一个二叉树结点
        {
            right=(bt)malloc(sizeof(tnode));        //
产生右孩子
            right->amount=min2;        //
次数值复制
            right->ch=min2_c;        //
字符复制
            right->left=NULL;
            right->right=NULL;
        }
        else
            right=min2_son;    //left
直接指向已经生成的二叉子树的根结点
        root=(bt)malloc(sizeof(tnode));
        root->amount=min1+min2;
        root->ch='/0';        //
对于计算产生的树结点,字符均为空
        root->left=left;
        root->right=right;
        //
二叉子树完成
        // 生成一个对应上面已产生二叉子树地址的链表结点
        made=(L)malloc(sizeof(Node));
        made->amount=root->amount;
        made->ch=root->ch;
        made->next=NULL;
        made->son=root;
        // 将生成的链表结点插入链表中
        temp_p=l;
        while(temp_p->next!=NULL)
            temp_p=temp_p->next;
        //
退出循环时 temp_p 指向链表最后一个结点
        temp_p->next=made;        //
将生成的结点插入链表
    }
    temp_p=l->next;
    return temp_p->son;
}
void encoding()        // 根据建立的哈夫曼树编码
{
    stack code,top,temp,readcode;
    bt r;
    huff temp_huff,hp;
    char huff[100]="";        //
用于存储当前字符的哈夫曼编码串
    int i,j,n=0;
    hlist=(hnode*)malloc(sizeof(hnode));
    hlist->ch='/0';
    for(i=0;i<100;i++)
        hlist->code[i]='/0';
    hlist->next=NULL;
    hp=hlist;    
    // 建立空栈
    code=(stack)malloc(sizeof(snode));
    code->amount=0;
    code->ch='/0';
    code->next=NULL;
    code->son=NULL;        //
栈的头结点指向树的根结点
    top=code;
    r=root;
    temp=(stack)malloc(sizeof(snode));    //
给哈夫曼树的根结点分配栈结点
    temp->amount=r->amount;
    temp->ch='0';
    temp->next=top;
    temp->son=r;
    top=temp;
    
    while(r!=NULL)    //
当前结点存在
    {
        if(r->left!=NULL&&r->left->amount!=-1)    //
当前结点有左孩子
        {
            r=r->left;        //r
转向左孩子
            r->amount=-1;
            temp=(stack)malloc(sizeof(snode));    // 给左孩子分配栈结点
            temp->amount=r->amount;
            temp->ch='0';
            temp->next=top;
            temp->son=r;
            top=temp;
        }
        else if(r->right!=NULL&&r->right->amount!=-1)        //
当前结点有右孩子
        {
            r=r->right;        //r
转向右孩子
            r->amount=-1;
            temp=(stack)malloc(sizeof(snode));    // 给右孩子分配栈结点
            temp->amount=r->amount;
            temp->ch='1';
            temp->next=top;
            temp->son=r;
            top=temp;
        }
        else    //
无未访问的孩子结点
        {
            
            if(r->left==NULL&&r->right==NULL)    //
当前结点为叶子结点
            {
                for(i=0;i<100;i++)    //
对哈夫曼编码数组初始化
                    huff[i]='/0';
                // 先输出该叶子结点的编码
                printf("
字符 %c, 编码为 :",r->ch);
                readcode=top;
                i=0;
                while(readcode!=code)
                {
                    huff[i++]=readcode->ch;        //
将栈元素倒置入哈夫曼编码数组中
                    readcode=readcode->next;
                }
                
                temp_huff=(hnode*)malloc(sizeof(hnode));    //
为当前字符及其编码创建结点
                temp_huff->ch=r->ch;        //
存储编码的原字符
                for(j=0;j<100;j++)        //
初始化编码串数组
                    temp_huff->code[j]='/0';
                j=0;
                for(i=i-2;i>=0;i--)                // 依次读出哈夫曼编码数组中的编码串
                {
                    printf("%c",huff[i]);
                    temp_huff->code[j++]=huff[i];
                }
                temp_huff->next=NULL;
                hp->next=temp_huff;
                hp=temp_huff;
                printf("/t/t");
                if(++n%2==0)
                    printf("/n");
            }
            if(top->next!=code)        // 若栈非空
            {
                top=top->next;
                r=top->son;
            }
            else
                break;
        }
    }
}
void describe_tree()    // 交互式显示哈夫曼树
{
    bt t;
    stack s,top,temp;
    int choice;
    s=(stack)malloc(sizeof(snode));
    s->amount=0;
    s->ch='/0';
    s->next=NULL;
    s->son=NULL;
    top=s;
    
    t=root;//t
指向哈夫曼树的根结点
    temp=(stack)malloc(sizeof(snode));    // 分配新栈结点
    temp->amount=t->amount;        
    temp->ch=t->ch;
    temp->next=top;        //
结点入栈
    temp->son=t;    //
将当前二叉树结点指针给栈顶结点
    top=temp;        //
修改栈顶指针
    printf(" 输入 1 往左子树,输入 2 往右子树,输入 3 返回父结点,输入 4 退出程序,其它输入无效 /n");
    scanf("%d",&choice);
    getchar();
    
    while(choice==1||choice==2||choice==3)
    {
        if(choice==1)        //
往左子树
        {
            if(t->left!=NULL)
            {
                t=t->left;
                temp=(stack)malloc(sizeof(snode));    //
分配新栈结点
                //
新结点入栈
                temp->amount=t->amount;        
                temp->ch=t->ch;
                temp->next=top;        //
结点入栈
                temp->son=t;    //
将当前二叉树结点指针给栈顶结点
                top=temp;        //
修改栈顶指针
                printf("%c,%d/n",t->ch,t->amount);
            }
            else    //
左子树不存在,当前结点已经是叶子结点
                printf("
无左孩子! /n");    
        }
        else if(choice==2)    //
往右子树
        {
            if(t->right!=NULL)
            {
                t=t->right;
                temp=(stack)malloc(sizeof(snode));    //
分配新栈结点
                //
新结点入栈
                temp->amount=t->amount;
                temp->ch=t->ch;
                temp->next=top;        //
结点入栈
                temp->son=t;    //
将当前二叉树结点指针给栈顶结点
                top=temp;        //
修改栈顶指针
                printf("%c,%d/n",t->ch,t->amount);
            }
            else    //
右子树不存在,当前结点已经是叶子结点
                printf("
无右孩子! /n");
        }
        else if(choice==3)    //
返回父结点
        {
            if(top->next!=s)    //
栈非空
            {
                top=top->next;
                t=top->son;
                printf("%c,%d/n",t->ch,t->amount);
            }
            else
                printf("
已经在根结点了! /n");
        }
        //else if(choice==4)    //
退出程序
        //    exit(0);
        scanf("%d",&choice);
        getchar();
    }
}

void codeoutput()    //
输出原始字符串的哈夫曼编码串
{
    huff hp;
    //char *s;
    int i;
    c=str;        //c
指向原始字符串 str 的首位置
    printf("/n/n
原始字符串为 :%s/n 哈夫曼编码为 :",c);
    code_sum=0;
    //
在编码链表中找寻与 c 匹配的编码串
    while(*c!='/0')        //
字符串未读完
    {
        hp=hlist->next;        //hp
指向编码链表的第一个字符编码组
        
        while(hp->ch!=*c&&hp->next!=NULL)    //
尚未找到匹配字符且后面还有字符
            hp=hp->next;
        //
退出循环的原因可能是找到了匹配字符,也可能是链表读完,需要进一步判断
        if(hp->ch==*c)    //
找到匹配字符
        {
            i=0;
            while(hp->code[i]!='/0')
                printf("%c",hp->code[i++]);            
        }
        code_sum+=i;
        c++;
    }
    printf("/n/n");
}
void analyze()    // 编码性能分析
{
    int n=0;
    printf("/t/t/t
性能分析中 .../n/n");
    while(pow(2,n)<char_num)    //
计算等长编码情况下需要的编码位数
        n++;
    printf("
等长码需要  %d  , 编码总长  %d  , 本次哈夫曼编码总长  %d ,  压缩比  %g/n",n,n*char_amount,code_sum,(float)code_sum/(n*char_amount));
}
main()
{
    int choice;
    //
初始化,操作包括建立空链表和键盘输入字符串
    initial();
    // 将接收的字符串依次读入链表中,并统计出现的次数
    pull_in_list();
    // 建立最优二叉树
    root=create();
    // 交互式显示哈夫曼树
    if(root!=NULL)
    {
        printf("/n
哈夫曼树构造完成,是否查看哈夫曼树,输入 1 查看,其它输入跳过 ");
        scanf("%d",&choice);
        getchar();
        if(choice==1)
            describe_tree();
    }
    else
    {
        printf("
哈夫曼树未建立,查看字符串中是否只含一种字符,或者重试 /n");
        exit();
    }
    // 要挟据建立的最优二叉树进行编码
    encoding();
    // 将原始字符串的哈夫曼编码串输出
    codeoutput();
    // 编码性能分析
    analyze();
    printf("/n/n/t/t/tAll Copyright Are Presevered By cobby/n/n 输入任何键退出 /n");
    scanf("%d",&choice);
}
六、排序
/* 
冒泡排序  */
#include<stdlib.h>
#include<stdio.h>
main()
{
    int i,j,temp,a[30000];
    long TIME=0;
    rand();
    for(i=0;i<30000;i++)
    {
        a[i]=rand();
        printf("%d/t",a[i]);
    }
    for(i=29999;i>=0;i--)
        for(j=0;j<=i;j++)
            if(a[j+1]<a[j])
            {
                TIME++;
                temp=a[j+1];
                a[j+1]=a[j];
                a[j]=temp;
            }
    for(i=0;i<=29999;i++)
        printf("%d/t",a[i]);
    printf("/n%d/n",TIME);
}

/*  
直接选择排序法  */
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
//#include<time.h>
main()
{
    int i,j,value,pos,temp,a[30000];
    long TIME=0;
    
    rand();
    for(i=0;i<30000;i++) /* make up the rand numbers*/
    {
        a[i]=rand();
        printf("%d/t",a[i]);
    }
    for(i=0;i<30000;i++)        /* sort */
    {
        value=a[i];
        pos=i;
        for(j=i+1;j<30000;j++)
        {
            TIME++;
            if(value>a[j])
            {
                value=a[j];
                pos=j;
            }
        }
        temp=a[i];
        a[i]=a[pos];
        a[pos]=temp;
    }
    for(i=0;i<30000;i++)
        printf("%d/t",a[i]);
    printf("/n/n%ld/n",TIME);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值