算法设计题

线性表

1.将两个递增的有序链表合并,要求结果链表任使用原来两个链表的存储空间,不另外占用其他存储空间。表中不允许有重复的数据。

void MergeList(Linelist &La,Linklist &Lb,LineList &Lc)
{//合并链表La,Lb,合并新的表使用头指针Lc指向
    pa=La->next;pb=Lb->next;//pa和pb分别是链表La,Lb的工作指针,初始化为相应的链表的第一个结点
    Lc=pc=La;//用La的头结点作为Lc的头结点。
    while(pa&&pb){
        if(pa->data<pb->data){pc->next=pa;pc=pa;pa=pa->data;}
        //取较小者La中的元素,将pa链接在pc的后面,pa指针后移。
        else if(pa->data>pb->data){pc->next=pb;pc=pb;pb=pc->data;}
        //取较小者Lb中的元素,将pb链接在pc的后面,pb指针后移。
        else {pc->next=pa;pc=pa;pa=pa->next;q=pb->next;delete pb;pb=q;}
        //相等时取La中的元素,删除Lb中的元素。
    }
    pc->next=pa?pa:pb;//插入剩余段
    delete Lb;//释放Lb的头结点

}

2.将两个递增的无序链表合并,要求结果链表任使用原来两个链表的存储空间,不另外占用其他存储空间。表中不允许有重复的数据。

void MergeList(Linelist &La,Linklist &Lb,LineList &Lc)
{//合并链表La,Lb,合并新的表使用头指针Lc指向
    pa=La->next;pb=Lb->next;//pa和pb分别是链表La,Lb的工作指针,初始化为相应的链表的第一个结点
    Lc=pc=La;//用La的头结点作为Lc的头结点。
    Lc->next=NULL;
    while(pa||pb){
        if(!pa){q=pb;pb=pb->next;}
        else if(!pb){q=pa;pa=pa->next;}
        else if(pa->data<=pb->data){q=pa;pa=pa->next;}
        //取较小者(相等)La中的元素,用q指向pb,pa指针后移。
        else {q=pb;pb=pb->next;}
        //取较小者Lb中的元素,用q指向pa,pb指针后移。(pa->data>pb->data)
        q->next=Lc->next;Lc->next=q
        //将q指向的结点插入Lc表的表头结点之后。
    }
    delete Lb;//释放Lb的头结点

}

栈和队列

入栈

Status push(LineStack &S,SElemType e)

{//在栈顶插入元素e

p->new StackNode;p->data=e;p->next=s;s=p;return ok;}

 出栈

Status pop(LineStack &S,SElemType &e)

{//删除s的栈顶元素,用e返回其值。

if(s==unll)return error;

e=s->data;p=s;s=s->next;delete p;return ok;}

队列

队空:Q.front==Q.rear

队满:(Q.rear+1)%MAXQsize==Q.front

队列长度:(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE

数组A[0...m]中,入队时操作:rear=(rear+1)%(m+1)

 1.判断回文

#define StackSize 100;
typedef char DataType;//假定栈元素的数据类型为字节。
typedef struct
{
DataType data[StackSize];
int top;
}SeqStack;

int IShuiwen(char *t)
{
    SeqStack s;
    int i,len;
    char temp;
    initStack(&s);
    len=Strlen(t);//求向量长度

    for(i=0;i<len/2,i++)
        Push(&s,t[i]);//将一半的字符入栈

    while(!EmptyStack(&s)){
        temp=pop(&s);
        if(temp!=s[i])return 0;//不等则返回0;
        else i++;
        }
    return 1;//比较完毕后均相等则返回1
}

串,数组和广义表

串是内容受限的线性表,它限定了表中的元素为字符。

串的模式匹配算法

BF算法:最简单直观。好O(n+m)  ,坏O(n*m)

KMP算法:next,nextval。

数组

数组一般不进行插入或删除的操作。

特殊矩阵的压缩存储

  1. 对称矩阵:n*n,则将n*n个元压缩存储到n(n+1)/2
  2. 三角矩阵:可分三角矩阵和下三角矩阵。
  3. 多对角矩阵
  4. 稀疏矩阵

广义表

  • A=()——A是一个空表,其长度为0;
  • B=(e)——B只有一个原子e,其长度为1;
  • C=(a,(b,c,d))——C的长度为2,两个元素分别为原子a和子表(b,c,d)。
  • D=(A,B,C)——D的长度为3,3个元素都是广义表,显然,将子表的值代入后,则有D=((),(e),(a,(b,c,d)))。
  • E=(a,E)——这是一个递归的表,其长度为2,E相当于一个无限的广义表E=(a,(a,(a...)))。

  • 取GetHead(LS):取出的表头为非空广义表的第一个元素,它可以是一个单原子,也可以是一个子表。
  • 取GetTail(LS):取出的表尾为除去表头之外由其余元素构成的表,即表尾一定是一个广义表。

GetHead(B)=e,GetTail(),

GetHead(D)=A,GetTail(B,C)。

广义表的存储结构:tag=1 | hp | tp (表结点),tag=0 | atom 原子结点

题目:写一个递归算法来实现字符串逆序存储,要求不另设串存储空间。

void Inver(char A[]){
//字符串逆序存储的递归算法
    char ch;
    static int i=0;//需要使用静态变量
    cin>>ch;
    if(ch!='.')
        {
            Inver(A);A[i++]=ch;//字符串逆序存储
        }
    
    A[i]='\0';//字符串结尾标记
    }

树和二叉树

哈夫曼树:左0,右1。没有度为1的结点。树中两个权值最小的结点一定是兄弟

1.统计二叉树树的叶结点个数

int LeafNodeCount(Bitree T){
if(T==unll)return 0;
else if(T->lchild==null&&T->rchild==null)return 1;
else return LeafNodeCount(T->lchild)+LeafNodeCount(T->rchild);
}

2.判别两棵树是否相等

int Compare(TreeNode*tree1;TreeNode *tree2){
bool tree1isnull=(tree1==null);
bool tree2isnull=(tree2==null);
if(tree1isnull!=tree2isnull){return 1;}
if(tree1isnull&&tree2isnull){return 0;}
if(tree1->c!tree2->c){return 1;}
return Compare(Tree1->left,Tree2->right)&Compare(Tree1->right,Tree2->left)
       Compare(Tree1->left,tree2->left)&Compare(Tree1->right,Tree2->right);
}

邻接矩阵

一个图的邻接矩阵表示是唯一的。

查找邻接矩阵的所有元素才能统计完毕,时间复杂度为O(n*n)

邻接表

不是唯一,因各个边结点链入顺序是任意的。

空间效率O(N+e)。统计边的数目O(N+e)。

邻接矩阵和邻接表的比较
比较项目邻接矩阵邻接表
无向图有向图无向图有向图
空间邻接矩阵对称可压缩至n(n-1)/2个单元邻接矩阵不对称可压缩至n*n个单元存储n+2e个单元存储n+e个单元
适用情况稠密图稀疏图

图的遍历

深度遍历DFS

类似先序遍历,栈结构来实现。

广度遍历BFS

类似层次遍历,队列结构来实现。

最小生成树

普里姆算法:核心思想归并点,时间复杂度为O(n*n),适用于稠密图。

克鲁斯卡尔算法:核心思想归并边,时间复杂度O(elog₂e),适用于稀疏图。

最短路径

迪杰斯特拉:Dijkstra从某个源点到其余各顶点的最短路径。时间复杂度为O(n*n)

费洛伊德算法:每一对顶点之间的最短路径。时间复杂度为O(n*n*n)

拓扑排序

重复选择没有直接前驱的顶点。时间复杂度为O(n+e)

拓扑排序可以判断出一个有向图是否有环。

关键路径

....

题目:

  1. 具有n个顶点的有向图最多有n(n-1)条边。
  2. 具有n个顶点的无向图最多有n(n-1)/2条边。
  3. n个顶点的连通图用邻接矩阵表示时,该矩阵至少有2(n-1)个非零元素。

查找

平衡二叉树:只要二叉树上有一个结点的平衡因子的绝对值大于1,则该二叉树就是不平衡的。

对包含n个元素的表进行顺序查找时,若查找每个元素的概率相等,则平均查找长度为(n+1)/2。-失败(n+1)。

排序

  1. 是一种选择排序。堆的形状是一棵完全二叉树
  2. 要求内存最大的是归并排序。(稳定)
  3. 希尔排序,快速排序,堆排序是不稳定的。
  4. 快速排序最好在被排序的数据完全无序。最坏是被排序的数据基本有序。
  5. 对n个关键字进行快速排序,最坏情况,时间复杂度是O(n*n)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值