数据结构算法Day04

本文介绍了链表操作的几个实例,包括删除循环链表中的最小元素直至链表为空,判断单链表是否有环,以及重新排列链表。此外,还探讨了栈和队列的应用,如队列元素的逆置,单链表的中心对称性检查,以及括号匹配的判断。这些算法深入展示了数据结构在实际问题中的应用。

19、设计一个带头结点的循环单链表,其结点值为正整数,设计算法反复找出链表内最小值并不断输出,并将结点从链表中删除,直到链表为空,再删除表头节点。

整体循环链表结束条件:L->next=L;

每趟找出最小值结束条件:p->next=L;

void delMinVal(LinkList &L){
    LNode *p,*pre;
    LNode *minp,*minpre;    
    while(L->next!=L){
        pre=L;
        p=L->next;
        minpre=L;
        minp=L->next;
        while(p!=L){
          if(p->data<=minp->data){
            minp=p;
            preminp=pre;
          }
          pre=p;
          p=p->next;
       }
        printf("%d\n",minp->data);
        preminp->next=minp->next;
        free(minp);
    }
    free(L);
}
        

20、判断单链表是否有环

设置快慢指针,fast与slow指针,每次slow指针移动一次,fast指针移动两次,当有环时,fast与slow必然会相遇,即fast=slow。

bool isLoop(LinkList L){
    LNode *fast,*slow;
    if(L){
       slow=L,fast=L;
       while(slow->next && fast->next){
          slow=slow->next;
          fast=fast->next->next;
          if(slow==fast){
            return true;
          }
       }
       return false;
    }
    return false;
}
          

21、给定一个单链表L(a1,a2,a3,....,an),将其重新排列为L(a1,an,a2,an-1,.....)

1、找出单链表的中间位置,可利用快慢指针,当fast指针指向链尾时,slow刚好指向中间位置

2、逆置表的后半部分

3、从前后两端依次各取一个结点进行重新排列

void change_list(LinkList &L){
    LNode *fast,*slow;
    LNode *p,*q;
    fast=slow=L;
    //寻找中间结点
    while(fast->next){
        slow=slow->next;
        fast=fast->next;
        if(fast->next) fast=fast->next;
    }//运行完毕后,slow指向的是链表的中间元素
    
    //将后半表结点逆置
    q=slow->next,slow->next=NULL;
    while(q){
        r=q->next;
        q->next=slow->next;
        slow->next=q;
        q=r;
    }
    
    //将后半表插入前半表
    p=slow->next;s=L->next;
    slow->next=NULL;
    while(p){
        r=p->next;
        p->next=s->next;
        s->next=p;
        s=p->next;
        p=r;
    }
}

三、栈、队列、字符串

1、Q是一个队列,S是一个空栈,编写算法使得队列中元素逆置

先将Q中的元素出队列依次入栈,再将栈中元素全部依次出栈入队列

void Reverse(Stack &S,Queue &Q){
    while(!QueueEmpty(Q)){
        x=DeQueue(Q);
        Push(S,x);
    }
    while(!StackEmpty(S)){
        Pop(S,x);
        EnQueue(Q,x);
    }
}

2、利用栈来判断单链表的全部n个字符是否中心对称

先让表中前半部分入栈,然后每次弹出栈与后半部分结点的值进行比较

int dc(LinkList L,int n){
    char s[n/2];
    LNode *p=L->next;
    for(int i=0;i<n/2;i++){
        s[i]=p->data;
        p=p->data;
    }
    i--;
    if(n%2==1){
        p=p->next;
    }
    while(p && p->data==s[i]){
        p=p->next;
        i--;
    }
    if(i==-1)
        return 1;
    else
        return 0;
}
   

3、判断一个表达式中括号是否配对

遇到左括号则入栈,碰到右括号判断类型是否匹配,匹配则继续进行,不匹配则直接停止,遍历结束后,栈为空则成功

bool bracketCheck(char str[],int len){
    SqStack S;
    InitStack(S);
    for(int i=0;i<len;i++){
        if(str[i]=='[' || str[i]=='(' || str[i]=='{')
            Push(S,str[i]);
        else{
            if(StackEmpty(S)) return false;
            char topElem;
            Pop(S,topElem);
            if(str[i]==')' && topElem !='(')
                return false;
            if(str[i]==']' && topElem !='[')
                return false;
            if(str[i]=='}' && topElem !='{')
                return false;
            }
    }
    return true;
}
            

4、假设一个序列为HSSHHHS,运用栈的知识,编写算法将S全部提到H之前,即为SSSHHHH

将序列字符为H的依次入栈,S重新进入序列,遍历完成后将栈中元素弹出加入序列中

void Ajust(char A[],int n){
    int j=0;
    SqStack S;
    InitStack(S);
    for(int i=0;i<n,i++){
      if(A[i]=='H'){
        Push(S,A[i]);
      }
      else{
        A[j]=A[i];
        j++;
      }
    }
    while(!StackEmpty(S)){
        Pop(S,A[j]);
        j++;
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值