数据结构与算法期末突袭专题

前言

本文总结了《数据结构与算法》中核心代码,可用作考前复习,但禁止任何个人或集体利用本文进行作弊或商用,一经发现将追究其法律责任。未经允许,禁止转载!

若您在阅读过程中发现任何格式或内容上的错误,望您能发送邮件至yc_ent@163.com反馈,我将及时修正相关内容!非常感谢每一位读者的支持。


第一部分 线性表

顺序存储

存储结构

//静态分配
typedef struct
{
    ElemType elem[MAXSIZE];
    int length;//顺序表当前长度
} SqList;
//动态分配
typedef struct
{
    ElemType *elem;
    int length;
    int listsize;
}SqList;

SqList L;

基本操作

//按位置插入
Status ListInsert(SqList &L,int i,ElemType e) 
{
    if(i>L.length+1 or L.length>=100 or i<1) return 0;
	L.length++;
	int temp;
    int j=L.length;
	while(j>=i)
	{
		L.elem[j]=L.elem[j-1];
        j--;
	}
    L.elem[i-1]=e;
	return 1;
}
//按位置删除
Status ListDelete(SqList &L,int i)
{
    if(i>L.length or i<1) return 0;
    L.length--;
    i--;
	while(i<L.length)
    {
        L.elem[i]=L.elem[i+1];
        i++;
    }
	return 1;
}

链式存储(单链表)

存储结构

//单链表结点结构定义
typedef struct LNode
{
    ElemType data;//数据域,存放数据元素
    struct LNode *next;//指针域,指向后继元素
}LNode,*LinkList;//单链表的类型名

//生成一个LNode型新结点
LNode p=(LNode *)malloc(sizeof(LNode));

//回收结点
free(p);

基本操作

//初始化
void InitList(SqList &L)
{
    L=(LNode *)malloc(sizeof(LNode));
    L->next=NULL;
    return OK;
}

//插入
struct LNode *insertFromHead(struct LNode *head,LNode *p)  //头插法处理函数
{
	if(p == NULL) head=p; //判断head是否创建有节点
    else
    {
		p->next=head;//将头节点,赋值给新创建的下一个节点
        head=p;//将新创建的结点的地址赋给头指针的结点
    }
    return head;//返回头节点
}
struct LNode *insertFromTail(struct LNode *head,LNode *p)  //尾插法处理函数
{
    LNode *point;
    point=(LNode *)malloc(sizeof(LNode));
    point=NULL;
    if(head==NULL)              
    {
        head=p;
        point=p;
	}
	else
    {
		while(point->next!=NULL) point=point->next;//让point指针指向下一个结点,保证它指向链表尾部 
		point->next=p;//让point指针指向的结点的next成员指向新建结点p
    }
    return head;
}

//查询
Status Get_LinkList(LinkList H, ElemType key)
{
    int index;
    LNode *p=(LNode *)malloc(sizeof(LNode));
    p=H->next;
    index=1;
    while(p->next!=NULL and p->data!=key)
    {
        p=p->next;
        index++;
    }
    if(p->next==NULL) return -1;
    else return index;
}

//取值
Status GetElem_L(LinkList L,int i,ElemType &e)
{
    LNode *p=(LNode *)malloc(sizeof(LNode));
    p=L->next; 
    int j=1;//初始化
    while(p&&j<i)//向后扫描,直到p指向第i个元系
    {
        p=p->next;
        ++j;
    }
    if(!p||j>i) return ERROR;//第i个元素不存在
    e=p->data;//取第i个元素
    return OK;
}

//删除
Status ListDelete(LinkList &L,char name[])
{
    LNode *p,*q;
    p=(LNode *)malloc(sizeof(LNode));
    q=(LNode *)malloc(sizeof(LNode));
    p=L;
    if(p->next==NULL) return ERROR;
    while(p->next!=NULL&&strcmp(name,p->next->data.name)!=0) p=p->next;
    if(p->next==NULL) return ERROR;
   
    q=p->next;//为释放节点做准备
    p->next=p->next->next;
    free(q);

    return OK;
}

拓展

循环链表的合并:

Void merge(LinkList La, LinkList &Lb)
{
    p=Lb->next;
    Lb->next=La->next;
    La->next=Lb->next->next;
    free(p);
}

循环链表的插入:

Status ListInsert_DuL(DuLinkList &L,int i,ElemType e)
{
    LNode *p=(LNode *)malloc(sizeof(LNode));
    p=L->next;
    int j=1;
    while (p!=L&&j<i) //双向循环链表
    {
        p=p->next;
        j++;
    }
    if ((p==L&&j<i)||j>i) return ERROR;

    s=(DuLNode *)malloc(sizeof(DuLNode));
    s->data=e;
    s->prior=p->prior;
    p->prior->next=s;
    s->next=p;
    p->prior=s;

    return OK;
}

双向链表的存储实现:

typedef struct DuLNode
{
    ElemType data;
    struct DuLNode *prior;
    struct DuLNode *next;
}DuLNode,*DuLinkList

双向链表的删除:

Status ListDelete_DuL(DuLinkList &L,int i,ElemType &e)
{
    LNode *p=(LNode *)malloc(sizeof(LNode));
    p=L->next;
    int j=1;
    while (p!=L&&j<i)
    {
        p=p->next;
        j++;
    }
    if (p==L||j>i) return ERROR;
    e=p->data;

    p->prior->next=p->next;
    p->next->prior=p->prior;
    free(p);

    return OK;
}

第二部分 栈和队列

顺序栈

存储结构

//方法一
typedef struct
{
    SElemType *base;//栈底指针
    SElemType *top;//栈顶指针
    int stacksize;//栈空间
}Sqstack;

//方法二
#define stacksize 100
typedef struct
{
    SElemType base[stacksize];
    int top;
}SqStack;

基本操作

//初始化
#define M 10
void InitStack(Sqstack &S)
{
    S.base=(SElemType *)malloc(M*sizeof(SElemType));
    S.top=S.base;
    S.StackSize=M;
}

//入栈
Status Push(Sqstack &S, SElemType x)
{
    if(S.top-S.base==S.stacksize)
    {
        S.base=(SElemType *)realloc(S.base,(S.stacksize+3)*sizeof(SElemType));
        S.top=S.base+S.stacksize;
        S.stacksize+=3;
    }
    /*if(S.top-S.base==S.stacksize) return ERROR;*/
    *S.top=x;
    S.top++;
    return OK;
}

//出栈
Status Pop(Sqstack &S, SElemType &e)
{
    if(S.base==S.top) return ERROR;
    S.top--;
    e=*S.top;
    return OK;
}

链栈

存储结构

typedef struct StackNode
{
    SElemType data;
    struct StackNode *next;
}StackNode,*LinkStack;

基本操作

//初始化
void InitStack(LinkStack &S)
{
    S=NULL;
}

//入栈
Status Push(LinkStack &S , SElemType e)
{
    StackNode*p=(StackNode *)malloc(sizeof(StackNode));//生成新结点p
    if(!p) return OVERFLOW;

    p->data=e;
    p->next=S;
    S=p;

    return OK;
}

//出栈
Status Pop(LinkStack &S,SElemType &e)
{
    if(S==NULL) return ERROR;

    e=S->data;
    p=S;
    S=S->next;
    free(p);

    return OK;
}

链队列

存储结构

//链队列结构
typedef struct Queue
{
    QucuePtr front; //队首指针
    QueuePtr rear; //队尾指针
}LinkQueue;
 
 
//结点
typedef Struct QNode
{
    QElemType data;//元素
    Struct QNode *next;//指向下一结点的指针
}QNode, *QueuePtr;

基本操作

//初始化
Status InitQueue(LinkQueue &Q)
{
    Q.front=Q.rear=(QNode *)malloc(sizeof(QNode));
    if(!Q.front) return OVERFLOW;
    Q.front->next=NULL;
    return OK;
}

//入队
Status EnLinkQueue(LinkQueue &Q,QElemType e)
{
    QNode *newNode=(QNode *)malloc(sizeof(QNode));
	if(newNode!=NULL)
	{
		newNode->data=e;
		newNode->next=NULL;
		Q.rear->next=newNode;
		Q.rear=newNode;
		return OK;
	}
	else return ERROR;
}

//出队
Status DeLinkQueue(LinkQueue &Q,QElemType &e)
{
    QNode *p=(QNode *)malloc(sizeof(QNode));
	if(Q.front==Q.rear) return ERROR;
	
    p=Q.front->next;
	Q.front->next=p->next;
	if(Q.rear==p) Q.rear=Q.front;  
	e=p->data;
	free(p);

	return OK;
}

//队判空
Status QueueEmpty(LinkQueue Q)
{
    if(Q.front==Q.rear) return TRUE;
	else return FALSE;
}

循环队列(顺序队列)

存储结构

typedef struct
{
  int *base;
  int front;//队头
  int rear;//队尾
}SqQueue;

基本操作

//初始化
void InitQ(SqQueue &Q,int N)
{
    Q.base=(int *)malloc(sizeof(int)*N);
    Q.front=Q.rear=0;
}

//入队
Status AddQ(SqQueue &Q, int x)
{
    if((Q.rear+1)%N==Q.front) return ERROR;
    else
    {
        Q.base[Q.rear]=x;
        Q.rear=(Q.rear+1)%N;
    }
    return OK;
}

//出队
Status DeleteQ(SqQueue &Q,int &e)
{
    if(Q.front==Q.rear) 
    {
        printf("Queue Empty\n");
        return ERROR;
    }
    else
    {
        e=Q.base[Q.front];
        Q.front=(Q.front+1)%N;
        return OK;
    }
}

第三部分 串、数组和广义表

串的运算

#include<string.h>
 
strcmp(char s1,char s2) //比较
strcpy(char to,char from) //复制
strcat(char to,char from) //连接
strlen(char s) //串长

存储结构

//定长顺序储存
#define MAXLEN 255
typedef struct
{
    char ch[MAXLEN+1];//0号单元不用
    int length;//串长度
}SString;

//堆式顺序储存
typedef struct 
{
    char *ch;//若串非空,则按串长分配存储区,否则ch为NULL
    int length;//串长度
}HString;

基本操作

//定长顺序存储串的联接
Status Concat(SString &T,SString S1,SString S2)
{
    if(S1.length+S2.length<=MAXLEN)//不截断
    {
        for(i=1;i<=S1.length;i++) T.ch[i]=S1.ch[i];
        for(i=1;i<=S2.length;i++) T.ch[i+S1.length]=S2.ch[i];
        T.length=S1.length+S2.length;
        uncut=TRUE;
    }
    else //截断
    {
        for(i=1;i<=S1.length;it+) T.ch[i]=S1.ch[i];
        for(i=1;i<=MAXLEN-S1.length;i++) T.ch[i+S1.length]=S2.ch[i];
        T.length = MAXLEN;
        uncut=FALSE;
    }
    return uncut;
}

//堆式顺序存储串的联接
Status Concat(HString &T, HString S1, HString S2)//用T返回由S1和S2联接而成的新串
{
    if (T.ch) free(T.ch);//释放旧空间
    T.ch =(char *)malloc((S1.length+S2.length)*sizeof(char));
    if(!T.ch) return OVERFLOW;
    T.length = S1.length + S2.length;
    for(i=1;i<=S1.length;i++) T.ch[i]=S1.ch[i];
    for(i=1;i<=S2.length;i++) T.ch[i+S1.length]=S2.ch[i];
    return OK;
}

串的模式匹配算法——BF算法

int Index(Sstring S,Sstring T,int pos)
{
    int i=pos,j=1;
    while(i<=S.length && j <=T.length)
    {
        if(S.ch[i]==T.ch[j])
        {
            ++i;
            ++j;
        }
        else
        {
            i=i-j+2;
            j=1;
        }
        if(j>T.length) return i-T.length;
        else return 0;
    }
}

数组

三元组存储结构

typedef struct
{
    int row, col;//行号,列号
    ElemType item;//非零元素值
}Triple;
 
typedef struct
{
    Triple data[MAXSIZE];//存储非零元素
    int mu, nu, tu;//行数,列数,非零元个数
}TSMatrix;

三元组转置算法

//转置算法1
Status Transpose(TSMatrix A,TSMatrix &B)
{
    B.mu=A.nu;
    B.nu=A.mu;
    B.tu=A.tu;
    if(B.tu)
    {
        int q=0;//q为B.data[]中三元组的下标
        for(int col=0;col<A.nu;++col)//扫描A.data[]A.nu遍
        for(int p=0;p<A.tu;++p)//p为A.data[]中三元组的下标
        {
            if (A.data[p].col==col)
            {
                B.data[q].row=A.data[p].col;
                B.data[q].col=A.data[p].row;
                B.data[q].item=A.data[p].item;
                ++q;
            }
    }
    return OK;
}

//转置算法2
Status FasTranspose (TSMatrix A, TSMatrix&B)
{
    B.mu=A.nu;
    B.nu=A.mu;
    B.tu=A.tu;
    if(B.tu) 
    {
        for(int col=0;col<A.nu;++col) num[col]=0;
        for(int t=0;t<A.tu;++t) ++num[A.data[t].col];
        cpot[0]=0;
        for(int col=1;col<A.nu;++col) cpot[col]=cpot[col-1]+num[col-1];
        for(int p=0;p<A.tu;++p)
        {
            col=A.data[p].col;
            int q=cpot[col];
            B.data[q].row=A.data[p].col;
            B.data[q].col=A.data[p].row;
            B.data[q].item=A.data[p].item;
            ++cpot[coll];
        }
        return OK;
}

第五部分 树和二叉树

二叉树

存储结构

//顺序存储
#define MAX_TREE_SIZE 100//二叉树的最大结点数
typedef TElemType SqBiTree[MAX_TREE_SIZE];//0号单元储存根节点
SqBiTree bt;

//二叉链表
typedef struct BiTNode//结点结构
{
    TElemTypedata;
    struct BiTNode *lchild, *rchild;//左右孩子指针
}BiTNode,*BiTree;

//三叉链表
typedef struct TriTNode
{
    TElemType data;
    struct TriTNode *lchild,*rchild,*parent;
}TriTNode,*TriTree;

基本操作

//建立
void CreateBiTree(BiTree &T) //先序建立二叉树
{
    Elemtype ch;
    scanf(&ch);
    if(ch=='#') T=NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiNode));
        T->data=ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}

//先序遍历
void PreOrder(BiTree T)
{
    if(T)//递归出口
    {
        printf(T->data);//访问根节点
        PreOrder(T->lchild);//递归遍历左子树
        PreOrder(T->rchild);//递归遍历右子树
    }
}
//中序遍历
void InOrderTraverse(BiTree T)
{
    if(T)
    {
        InOrderTraverse(T->lchild);
        printf(T->data);
        InOrderTraverse(T->rchild);
    }
} 
//后序遍历
void PostOrderTraverse(BiTree T)
{
    if(T)
    {
        PostOrderTraverse(T->lchild);
        PostOrderTraverse(T->rchild);
        printf(T->data);
    }
}

//结点计数
int NodeCount(BiTree T)
{
    if(T==NULL) return 0;
    else return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}

//叶子计数
int LeadCount(BiTree T)
{
    if(T==NULL) return 0;//如果是空树返回0
    if(T->lchild==NULL && T->rchild==NULL) return 1;//如果是叶子结点返回1
    else return LeafCount(T->lchild)+LeafCount(T->rchild);
}

//计算深度
int Depth(BiTree T)
{
    if(T==NULL) return 0;
    else
    {
        m=Depth(T->lchild);
        n=Depth(T->rchild);
        if(m>n) return (m+1);
        else return (n+1);
    }
}

//查找
BiTree search(BiTree T, ElemType x)
{
    if(T==NULL) return NULL;
    else
    {
        if(T->data==x) return T;
        if(p=search(T->lchild,x)) return p;//在左子树中查找
        return search(T->rchild,x);//在右子树中查找
    }
}

哈夫曼树(最优二叉树)

哈夫曼算法

typedef struct
{
    int weght;
    int parent,lchild,rchild;
}HTNode,*HuffmanTree;
 
void Select(HuffmanTree HT,int len,int &s1,int &s2)
{
    int i,min1=32767,min2=32767;
    for(i=1;i<=len;i++)
    {
        if(HT[i].weight<min1&&HT[i].parent==0)
        {
            s2=s1;
            min2=min1;
            min1=HT[i].weight;
            s1=i;
        }
        else if(HT[i].weight<min2&&HT[i].parent==0)
        {    
            min2=HT[i].weight;
            s2=i;
        }
    }
}
 
void CreateHuffmanTree(HuffmanTree & HT,int n)//构造哈夫曼树HT
{
    if (n<=1) return;
    int m=2*n-1;
    HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
    for(int i=1;i<=n;i++) scanf(HT[i].weight);
    for(int i=1;i<=m;++i)
    {
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
    }
    //初始化工作结束,下面开始创建哈夫曼树
    for(int i=n+1;i<=m;++i)
    {
        Select(HT,i-1,s1,s2);
        //在HT[1..i-1]选择parent为0且weight
        //最小的两个结点,其序号分别为s1和s2
        HT[s1].parent=i;
        HT[s2].parent=i;
        HT[i].lchild=s1;
        HT[i].rchild=s2;
        HT[i].weight=HT[s1].weight+ HT[s2].weight;
    }
}
 
typedef char **HuffmanCode;
 
void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)//从叶子到根逆向求每个字符的哈夫曼编码
{
    char *cd=(char*)malloc(n*sizeof(char));
    cd[n-1]='\0';
    HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
    for(int i=1;i<=n;++i)
    {
        int start=n-1;
        int c=i;
        int f=HT[i].parent;
        while(f!=0)
        {
            --start;
            if(HT[f].lchild==c) cd[start]='0';
            else cd[start]='1';
            c=f;
            f=HT[f].parent;
        }
        HC[i]=(char*)malloc((n-start)*sizeof(char))
        strcpy(HC[i],&cd[start]);
    }
    free(cd);
}

第六部分 图

图的建立

邻接矩阵存储

//用两个数组分别存储顶点表和邻接矩阵
#define MaxInt 32767 //表示极大值,即∞
#define MVNum 100//最大顶点数
typedef char VerTexType;//假设顶点的数据类型为字符型
typedef int ArcType;//假设边的权值类型为整型
typedef struct
{
    VerTexType vexs[MVNum];//顶点表
    ArcType arcs[MVNum][MVNum];//邻接矩阵
    int vexnum,arcnum;//图的当前点数和边数
}AMGraph;
//采用邻接矩阵表示法,创建无向网(UDN算法)
Status CreateUDN(AMGraph &G)
{
    scanf(&G.vexnum,&G.arcnum);
    getchar()//吃回车
    for(int i=0;i<G.vexnum;++i) scanf("%c",&G.vexs[i]);
    getchar()//吃回车
    for(int i=0;i<G.vexnum;++i) for(int j=0; j<G.vexnum;++j) G.arcs[i][j]=MaxInt;//初始化所有位置为极大值
    for(int k=0;k<G.arcnum;++k)//构造邻接矩阵
    {
        char v1,v2;
        int w;
        scanf("%c %c %d",&v1,&v2,&w);//输入一条边依附的顶点及权值
        getchar()//吃回车
        //若无边权,则w=1
        int i=LocateVex(G,v1);
        int j=LocateVex(G,v2);//确定v1和v2在G中的位置
        G.arcs[i][j]=w;//边<v1,v2>的权值置为w
        G.arcs[j][i]=G.arcs[i][j];//置<vl, v2>的对称边<v2,v1>的权值为w
    }
    return OK;
}
 
int LocateVex(MGraph G,VertexType u)
{
    //存在则返回u在顶点表中的下标,否则返回-1
    for(int i=0;i<G.vexnum;++i) if(u==G.vexs[i]) return i;
    return -1;
}
 

邻接表存储

#define MVNum 100
typedef struct ArcNode
{
    int adjvex;//该边所指向的顶点的位置
    struct ArcNode *nextarc; //指向下一条边的指针
    InfoType info;//该边相关信息
}ArcNode;
typedef struct VNode
{
    VerTexType data;//顶点信息
    ArcNode *firstarc;//指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum]//AdjList表示邻接表类型
typedef struct
{
    AdjList vertices; //邻接表
    int vexnum,arcnum;//图的当前顶点数和边数
}ALGraph;

Status CreateUDG(ALGraph &G)//采用邻接表表示法,创建无向图G
{
    scanf("%d%d",&G.vexnum,&G.arcnum);//输入总顶点数,总边数
    for(int i=0;i<G.vexnum;++i)//输入各点,构造表头结点表
    {
        scanf("%d",&G.vertices[i].data);//输入顶点值
        G.vertices[i].firstarc=NULL;//初始化表头结点的指针域为NULL
    }
    for(int k=0;k<G.arcnum;++k)//输入各边,构造邻接表
    {
        int v1,v2;
        scanf("%d %d",&v1,&v2);//输入一条边依附的两个顶点
        int i=LocateVex(G,v1); 
        int j=LocateVex(G,v2);

        ArcNode *p1=(ArcNode *)malloc(sizeof(ArcNode));
        p1->adjvex=j;//邻接点序号为j
        p1->nextarc= G.vertices[i].firstarc;
        G.vertices[i].firstarc=p1;//将新结点*p1插入顶点vi的边表头部

        ArcNode *p2=(ArcNode*)malloc(sizeof(ArcNode));
        p2->adjvex=i;//邻接点序号为i
        p2->nextarc=G.vertices[j].firstarc;
        G.vertices[j].firstarc=p2;//将新结点*p2插入顶点vj的边表头部
    }
    return OK;
}

图的遍历

深度优先遍历算法

//邻接矩阵
int visited[MVNum];
void DFSTraver(AMGraph G)//非连通图的遍历
{
    //初始化顶点访问标志数组
    for(int i=0; i<G.vexnum;i++) visited[i]=0;
    //反复调用DFS过程,遍历图
    for(int i=0; i<G.vexnum;i++) if(visited[i]==0) DFS(G,i);
}
void DFS(AMGraph G,int v)//图G为邻接矩阵类型
{
    printf("%c ",G.vexs[v]); 
    visited[v]=1;//访问第v个顶点
    for(int w=0; w< G.vexnum; w++)//依次检查邻接矩阵v所在的行
        if((G.arcs[v][w]!=0)&&(!visited[w])) DFS(G, w);//w是v的邻接点,如果w未访问,则递归调用DFS
}//时间复杂度为O(n²)

//邻接表
void DFS(ALGraph G,int v)//图G为邻接表类型
{
    printf("%d ",G.vertices[v].data); 
    visited[v]=1;//访问第v个顶点
    ArcNode *p=(ArcNode *)malloc(sizeof(ArcNode));
    p=G.vertices[v].firstarc;//p指向v的边链表的第一个边结点
    ArcNode *w=(ArcNode *)malloc(sizeof(ArcNode));
    while(p!=NULL)//边结点非空
    {
        w=p->adjvex;//表示w是v的邻接点
        if(!visited[w]) DFS(G, w);//如果w未访问,则递归调用DFS
        p=p->nextarc;//p指向下一个边结点
    }
}//时间复杂度O(n+e)

广度优先遍历算法

//邻接矩阵
void BFSTraverse(Graph G)//非连通图
{
    for(int v=0;v<G.vexnum;++v) visited[v]=0;//初始化访问标志
    for(int v=0;v<G.vexnum;++v) if(!visited[v]) BFS(G,v);
}

void BFS(Graph G,int v)//按广度优先非递归遍历连通图G
{
    printf(v);
    visited[v]=1;//访问第v个顶点
    InitQueue(Q);//辅助队列Q初始化,置空
    EnQueue(Q,v);//v进队
    while(!QueueEmpty(Q))//队列非空
    {
        DeQueue(Q,u);//队头元素出队并置为u
        for(int w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))
        {
            if(!visited[w])//w为u的尚未访问的邻接顶点
            {
                printf(w);
                visited[w]= 1; 
                EnQueue(Q,w); //w进队
            }
        }
    }
}

最小生成树构造算法

Prim算法

//记录从顶点集U到V-U的代价最小的边的辅助数组定义
struct{
    VertexType adjvex;//V-U中的某个点到U中最小边的对应邻接点位置
    int lowcost;//对应的最小边的权值
}closedge[MAX_VERTEX_NUM];

int Min(AMGraph G)
{
	int i;
	int index = -1;
	int min = MaxInt;
	for(i = 0 ; i < G.vexnum ; ++i){
		if(min > closedge[i].lowcost && closedge[i].lowcost != 0){
			min = closedge[i].lowcost;
			index = i;
		}
	}
	return index;
}

void MiniSpanTree_Prim(AMGraph G, char u)
{ 
	int k , j , i;
	char u0 , v0;
    k =LocateVex(G, u);//辅助数组初始化
    for(j = 0; j < G.vexnum; ++j)
    { 
		if(j != k)//起始点V1并入U(={V1})
        {
			closedge[j].adjvex = u;
			closedge[j].lowcost = G.arcs[k][j];
		}
	}
	for(i = 1; i < G.vexnum; ++i)//选择其余顶点的G.vexnum-1个顶点
    {
		k = Min(G);//求下一个顶点:第k顶点
		u0 = closedge[k].adjvex;
		v0 = G.vexs[k]; 
        printf("%d %d\n",u0,v0);//输出生成树的边
		closedge[k].lowcost = 0; //第k顶点并入U,考虑加入顶点K后closedge数组的变化
		for(j = 0; j < G.vexnum; ++j) //重新选择最小边
			if(G.arcs[k][j] < closedge[j].lowcost)
            {
				closedge[j].adjvex = G.vexs[k];
				closedge[j].lowcost = G.arcs[k][j];
			}
	}
}

Kruskal算法

typedef struct{ 
	char vexs[MVNum];
	int arcs[MVNum][MVNum];
	int vexnum,arcnum; 
}AMGraph;

struct Evode{
	char Head;
	char Tail;
	int lowcost;
}Edge[(MVNum * (MVNum - 1)) / 2];

int Vexset[MVNum];

int LocateVex(AMGraph G , char v){
	for(int i = 0; i < G.vexnum; ++i)
		if(G.vexs[i] == v)
			return i;
		return -1;
}

void CreateUDN(AMGraph &G){ 
	int i , j , k;
	char c;
    scanf("%d %d",&G.vexnum,&G.arcnum);	
	getchar();
    for(i = 0; i < G.vexnum; ++i){   
		G.vexs[i]=getchar();
	}
	getchar();
    for(i = 0; i < G.vexnum; ++i)  
		for(j = 0; j < G.vexnum; ++j)   
			G.arcs[i][j] = MaxInt;
	for(k = 0; k < G.arcnum;++k){
		char v1 , v2;
		int w;
		scanf("%c %c %d",&v1,&v2,&w);
		getchar();
		i = LocateVex(G, v1);  j = LocateVex(G, v2); 
		G.arcs[i][j] = w;
		G.arcs[j][i] = G.arcs[i][j];
		Edge[k].lowcost = w;
		Edge[k].Head = v1;
		Edge[k].Tail =v2;
	}
}

void Sort(AMGraph G){
	int m = G.arcnum - 2;
	int flag = 1;
	while((m > 0) && flag == 1){
		flag = 0;
		for(int j = 0 ; j <= m ; j++){
			if(Edge[j].lowcost > Edge[j+ 1].lowcost){
				flag = 1;
				struct Evode temp=Edge[j];
				Edge[j]=Edge[j + 1];
				Edge[j + 1]=temp;
			}
		}
		--m;
	}
}

void MiniSpanTree_Kruskal(AMGraph G){ 
    int i , j , v1 , v2 , vs1 , vs2;
	Sort(G);  
	for(i = 0; i < G.vexnum; ++i) 
        Vexset[i] = i;
    for(i = 0; i < G.arcnum; ++i){      
		v1 =LocateVex(G, Edge[i].Head); 
		v2 =LocateVex(G, Edge[i].Tail); 
		vs1 = Vexset[v1];
		vs2 = Vexset[v2]; 
		if(vs1 != vs2){
			printf("%c->%c\n",Edge[i].Head ,Edge[i].Tail); 
			for(j = 0; j < G.vexnum; ++j)
				if(Vexset[j] == vs2) Vexset[j] = vs1;
		}
    }
}

最短路径算法

Dijkstra算法

void Dijkstra(Graph G, int v)
{
	//初始化
	int n = G.vexnum;//n为图的顶点个数
	for (int i = 0; i < n; i++)
	{
		S[i] = false;
		D[i] = G.Edge[v][i];
		if (D[i] < INF)Pr[i] = v; //v与i连接,v为前驱
		else Pr[i] = -1;
	}
	S[v] = true;
	D[v] = 0;
	//初始化结束,求最短路径,并加入S集
	for (int i = 1; i < n; i++)
	{
		int min = INF;
		int temp;
		for (int w = 0; w < n; w++)
			if (!S[w] && D[w] < min) //某点temp未加入s集,且为当前最短路径
			{
				temp = w;
				min = D[w];
			}
		S[temp] = true;
        //更新从源点出发至其余点的最短路径 通过temp
		for (int w = 0; w < n; w++)
		{
            if (!S[w] && D[temp] + G.Edge[temp][w] < D[w])
			{
				D[w] = D[temp] + G.Edge[temp][w];
				Pr[w] = temp;
			}
        }
	}
}

拓补排序算法

#include <stdio.h>
//#include "conio.h"
#include <stdlib.h>
#include <string.h>
#define  TRUE   1
#define  FALSE  0
#define  OK     1
#define  ERROR  0
#define  OVERFLOW  -1
#define MAXSIZE 30
#define VERTEX_MAX 30 //最大顶点数
#define VEX_NUM 10
typedef int Status;
typedef char Vextype[20]; //顶点类型
typedef int ElemType;
typedef struct //定义顺序栈结构
{ 
    ElemType elem[MAXSIZE];
    int top;
}SeqStack;                             
typedef struct node //边结点定义
{
    int  adjvex; //邻接点域
    struct node *next; //指向下一个边结点的指针域
}EdgeNode;
typedef struct vnode //表头结点定义
{ 
    int Indegree; //顶点入度域
    Vextype vertex; //顶点信息
     EdgeNode *firstedge;
}VertexNode;
typedef struct //图的邻接表存储
{ 
    VertexNode adjlist[VERTEX_MAX];
    int n,e; //顶点数和边数
}ALGraph;
 
 
void InitStack_Sq(SeqStack &s) //初始化栈操作
{
    s.top=-1;
}
int Empty_Sq(SeqStack s) //判栈是否为空
{
    if(s.top==-1) return 1;
    else return 0;
}
Status Push_SeqStack(SeqStack &s, ElemType x)
{
    if(s.top==MAXSIZE-1) return OVERFLOW; //栈满不能入栈
    else
    {
        s.top++;
        s.elem[s.top]=x ;
        return OK;
   }
} 
Status Pop_SeqStack(SeqStack &s,ElemType &y)
{
    if(Empty_Sq(s)) return OVERFLOW; //栈空不能出栈
    else
    {
        y=s.elem[s.top];
        s.top--;  
        return OK;
     }//栈顶元素存入*y,返回
}
void CreateALGraph(ALGraph &G) //创建有向图的邻接表
{ 
    int i,v,w;
    int Indegree[VERTEX_MAX]={0};
    EdgeNode *s;
    scanf("%d,%d",&(G.n),&(G.e)); //输入顶点数n和弧数m
    for (i=0;i<G.n;i++)
    {
        scanf("%s",G.adjlist[i].vertex);
        G.adjlist[i].firstedge=NULL;
    }
    for(w=0;w<G.e;w++) //建立边表
    {
        scanf("%d,%d",&i,&v);
        s=(EdgeNode*)malloc(sizeof(EdgeNode));
        s->adjvex=v;
        Indegree[v]++; //统计各顶点的入度
        s->next=G.adjlist[i].firstedge; //前插方法
        G.adjlist[i].firstedge=s;
     }
    for(i=0;i<G.n;i++) G.adjlist[i].Indegree=Indegree[i];
}
void topsort( ALGraph &G)
{
    int i,v,w;
    int cnt=0;//计数器初始化为0
    EdgeNode *ptr;
    SeqStack st;
    InitStack_Sq(st);
    for(i=0;i<G.n;i++) if(G.adjlist[i].Indegree==0) Push_SeqStack(st,i);
    while(!Empty_Sq(st))
    {
        Pop_SeqStack(st, v); //出栈一次,出栈元素放在v中
        printf("%s ",G.adjlist[v].vertex);
        cnt++;
        ptr=G.adjlist[v].firstedge; //ptr指向第一个边结点
        while(ptr!=NULL) //只要有边
        {
            w=ptr->adjvex;
            G.adjlist[w].Indegree--;
            if(G.adjlist[w].Indegree==0) Push_SeqStack(st,w);
            ptr=ptr->next;
        }
    }
    if(cnt<G.n) printf("后续无法输出!\n");
} 
int main()
{
    ALGraph g;
    CreateALGraph(g);
    printf("拓扑序列为:");
    topsort(g);
    return 0;
}

第七部分 查找

线性表的查找

顺序查找(线性查找)

/*不用监视哨法,在顺序表中查找关键字等于key的元素*/
int SeqSearch (sSTable ST,KeyType key)
{
    int i=ST.length;
    while (i>=1&&ST.R[i].key!=key) i--;
    return i;
}

/*监视哨法*/
int Search_Seq(SSTable ST,KeyType key)
{
    ST.R[0].key=key;
    for(i=ST.length;ST.R[i].key!=key;--i);
    return i;
}

折半查找(二分查找、对分查找)

//非递归算法
int Search_Bin(SSTable ST,KeyType key)//若找到,则函数值为该元素在表中的位置,否则为0
{
    low=1;
    high=ST.length;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(key==ST.R[mid].key) return mid;
        else if(key<ST.R[mid].key) high=mid-1;//前一子表查找
        else low=mid+1;//后一子表查找
    }
    return 0;//表中不存在待查元素
}

//递归算法
int Search_Bin (SSTable ST,keyType key,int low,int high)
{
    if(low>high) return 0; //查找不到时返回0
    mid=(low+high)/2;
    if(key=-ST.elem[mid].key) return mid;//查找成功
    else if(key<ST.elem[mid].key) return Search_Bin (ST,key,low,mid-1);//递归
    else return Search_ Bin(ST,key,mid+1,high);//递归
}

树的查找

二叉排序树的操作

//查找
BSTree SearchBST(BSTree T,KeyType key)
{
    if(!T || key=T->data.key) return T;
    else if(key < T->data.key) return SearchBST(T->lchild,key);//在左子树中继续查找
    else return SearchBST(T->rchild,key);//在右子树中继续查找
}

//插入
void InsertBST (BSTree &T,ElemType e)
{
    if(!T)
    {
        S= (BSTNode *)malloc(sizeof(BSTNode));
        S->data=e;
        S->lchild=S->rchild=NULL;
        T=S;
    }
    else if(e.key < T->data.key) InsertBST(T->lchild,e);
    else if(e.key > T->data.key) InsertBST(T->rchild,e);
}

哈希(散列/杂凑)表的查找

除留余数法 Hash(key)=key mod p(p是一个整数)

#define NULLKEY 0
typedef struct
{
    int key;
}HashTable[m];

void CreateHash(HashTable HT[],int key)
{
    int H0=key%13;
    int Hi;
    if (HT[H0].key==NULLKEY)
    {
        HT[H0].key=key; 
        return;
    }
    else
    {             
        for(int i=1;i<m;++i)
        {                
            Hi=(H0+i)%m;
            if (HT[Hi].key==NULLKEY)
            {
                HT[Hi].key=key; 
                return;
            }
        }
    }
}

int SearchHash(HashTable HT,int key)
{
    int H0=H(key);//H(key)为哈希函数
    if(HT[H0].key==NULLKEY) return -1;
    else if(HT[H0].key==key) return H0;
    else
    {
        for(int i=1;i<m;++i)
        {
            int Hi=(H0+i)%m;//线性探测
            if(HT[Hi].key==NULLKEY) return -1;
            else if(HT[Hi].key==key) return Hi ;
        }
        return -1;
    }
}

第八部分 排序

直接插入排序

typedef struct
{
    ElemType r[MAXSIZE+1];
    int length;
}SqList;
 
void InsertSort (SqList &L)
{
    int i,j;
    for(i=2;i<=L.length; ++i)
    {
        if(L.r[i].key<L.r[i-1].key)//注只有当前元素比前一个元素的值小的时候才需要进行移动
        {
            L.r[0]=L.r[i];//设置“监视哨”同时暂存插入元素值
            L.r[i]=L.r[i-1];
            for(j=i-2;L.r[0].key<L.r[j].key;j--) L.r[j+1]=L.r[i];//从后向前比较直到发现不比L.r[0]大的元素为止
            L.r[j+1]=L.r[0];
        }
    }
}

冒泡排序

void BubbleSort(SqList &L)
{
    for (int i=1;i<L.length;i++)
    {
        int Exchange=0;
        for (int j=1;j<=L.length-i;j++)
        {
            if (L.r[j+1]<L.r[j])
            {
                int temp=L.r[j+1]
                L.r[j+1]=L.r[i];
                L.r[i]=temp;
                Exchange=1;
            }
        }
        if(Exchange==0) return;
    }
}

快速排序

void QSort (Sqlist &L,int low,int high)
{
    if (low<high)
    {
        int pivotloc=Partition(L,low,high);
        QSort(L,low,pivotloc-1);
        QSort(L, pivotloc+1, high);
    }
}
 
int partition(sqlist &L,int low,int high) 对从下标low到high的顺序表做一趟快速排序
{
    int pivotkey=L.r[low];
    while(low<high)//将低下标设置为枢轴
    {
        while(low<high&&L.r[high]>=pivotkey) --high;
        L.r[low]=L.r[high];
        while(low<high&&L.r[low]<=pivotkey) ++low;
        L.r[high]=L.r[low];
    }
    L.r[low]=pivotkey;
    return low;//返回值是枢轴的排序位置
}

选择排序

void SelectSort (SqList &L)//对顺序表L作简单选择排序
{
    for(int i=1;i<L.length;++i)//选择第i小的记录,并交换到位
    {
        //在L.r[i..L. 1ength]中选择key最小的记录
        int min=i ;
        for(int j=i+1;j<=L.1ength;j++) if(L.r[j]<L.r[min]) min=j;
        if(i!=min)//与第i个记录交换
        {
            int temp=L.r[i];
            L[i]=L.r[min];
            L.r[min]=temp;
        }
    }
}

堆排序

void Sift(int R[],int low,int high)
{
    int i=low,j=2*i; 
    int temp=R[i];
    while (j<=high) 
    {    
      if (j<high && R[j]<R[j+1])
        j++; 
        if (temp<R[j]) 
        {    
            R[i]=R[j];
            i=j;   
            j=2*i;
        }
        else break;                         
    }
    R[i]=temp;                              
}
 
void HeapSort(int R[],int n)    
{
    int i,j;
    int temp;
    for(i=n/2;i>=1;i--)      
       Sift(R,i,n); 
    for(i=n;i>=2;i--)       
    {      
       swap(R[1],R[i]); //将R[1]与R[i]进行交换。
       Sift(R,1,i-1); 
    }
}
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yhan计算机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值