整理几个简单有趣算法题(数据结构篇)

一、【题目描述】

    有两个整数序列A=(a1,a2,......,an)和B=(b1,b2,......bn),分别用带头结点的单链表ha和hb存储,设计一个算法int SubList(LinkList ha,LinkList hb)用于判断B是否为A的连续子序列,若是,返回1,否则返回0.

单链表中的结点的存储结构定义为:

typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode,*LinkList;

【思考】

   首先看到这个就是简单的字符串匹配的问题,这个我们在KMP算法和BF算法里面有提到过,但是这个明显没有那么复杂,我们只需要不停的做循环查找即可,而且因为只是写出算法,不需要具体的程序实现,所以我们就有:

【解】

int SubList(LinkList ha,LinkList hb)
{
    LNode *pa=ha->next,*pb,*pa1;
    while(pa)
    {
        pb = hb->next;
        pa1 = pa;
        while(pa1&&pb&&pa1->data==pb->data)
        {
            pa1=pa1->next;
            pb=pb->next;
        }
        if(!pb)
            return 1;
        pa=pa->next;
     }
    return 0;
}

简单的描述一下,主串和子串都从第一个开始读取,数值相等指针往下,不等,主串加一,如果主串未读完,子串读完匹配完成,返回1。否则主串读完没有找到,返回零。

 

二、【题目描述】

    设计一个算法void Insert(LinkList L,int x)在带头结点的非空单链表L中第一个最大值结点(最大值结点可能有多个)之前插入一个值为x的结点。

单链表中的结点的存储结构定义为:

typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode,*LinkList;

【思考】

    这只是一个简单的单链表的插入操作,不同的就是需要找到最大值的结点,这个操作有很多种,这里我们就直接借用辅助指针来实现找到最大值的操作,然后将值插入此结点的前面。

【解】

void Insert(LinkList L,int x)
{
    LNode *pre = L,*p=L->next;//一般的插入都是有一个辅助指针指向插入的前一个,然后再来
    LNode *maxpre=L,*maxp=L->next;//一个指向要插入数值的指针,然后再有一个遍历的指针
    LNode *s;//所以我们这里会发现,我定义了5个指针,因为除了常规的3个,需要有最大值
    while(p)//最大值的前驱
    {
        if(maxp->data<p->data)//找到最大值,依次交换
        {
            maxp=p;
            maxpre=pre;
        }
        pre = p;
        p= p->next;
     }
    s=new LNode;
    s->data=x;
    s->next=maxpre->next;
    maxpre->next=s;
}

此处在解释一下,题中有指向最大值的最大值指针,最大值前面的指针,p指针作为遍历,p的前面的指针,还有一个指向x的指针s。所以很好理解就只有简单的插入操作。

 

三、【题目描述】

  设计在链式存储结构上建立一颗二叉树的算法。其中二叉树的结点结构如下

typedef struct node
{
    int key;
    struct node*lchild,*rchld;
}bitree;

【思考】

    一看,一看结构体就知道是简单的左右孩子的存储结构,那么就利用递归来建立二叉树吧。

【解】

void createbitree(bitree*&bt)
{
    char ch;cin>>ch;
    if(ch=='#'){bt=0;return}
    bt=new bitree;
    bt->data = ch;
    createbitree(bt->lchild);
    createbitree(bt->rchild);
}

这个具体的实现代码在我的数据结构专栏里面有。

 

四、【题目描述】

    设有两个集合A和B,要求设计生成集合C=A\capB的算法,其中结合A、B和C用链式结构表示。存储结构有:

typedef char datatype;
typedef struct node{
    int data;
    stuct node*next;
}LinkList;

【思考】

    首先对于交集大家都是很清楚的,这里就是相同的元素就放到C中,所以我们具体来看看算法代码。

【解】

void intersection(LinkList *ha,LinkList *hb,LinkList *&hb)
{
    LinkList *p,*q,*t;
    for(p=ha,hc=0;!p=0;p=p->next)
    {    
        for(q=hb;q!=0;q=q->next)
        if(q->data==p->data) break;
        if(q!=0)
        {
            t=new LinkList;
            t->data=p->data;
            t->next=hc;
            hc = t;
        }
    }
}

有了上一个的经验,这里我们就可以清晰的看到我们就是需要从从遍历,所以两个for循环,如果相等就把值赋给C

 

后记:

   像这样的算法题就有很多,线性表中,栈和队列,二叉树,图论里面都有很多这样的例子。查找排序这个也可以取查看其它的资料例子。如果有误,请评论指出,谢谢。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

threecat.up

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

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

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

打赏作者

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

抵扣说明:

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

余额充值