考研数据结构-单链表(综合应用2)

本节题目来自王道单科37页。说不定哪天就放弃了在电脑上敲代码了,好费时啊啊啊啊。

 

6、有一个带头结点的单链表L,设计一个算法使其递增有序。

分析:排序问题。如果没有说不能用辅助数组的话,可以把它复制进数组,快排后再尾插法插入链表中。

这里我们直接在链表中用直接插入排序,即先把前面的一个元素先看作有序,从第二个元素开始遍历。设立三个指针,p用于遍历,pre用于记录插入位置,r用于记录p后继指针,防止断链。r=p->next;   p=r;   事实上是经常会有的操作。

void Sort(LinkList &L){
    LNode *p,*pre,*r;
    p=L->next;
    r=p->next;  //r保持*p后继结点指针,以保持不断链 
    p->next=NULL;   //构造只含有一个数据元素的有序表 
    p=r;        //不要忘了这句  ,从第二个元素开始遍历 
    while(p!=NULL){
        r=p->next;
        pre=L;   //pre每次都要在前面的有序表中从头遍历
        while(pre->next!=NULL&&pre->next->data<p->data)  //找到有序表中第一个比p大的结点,并插到其前面
            pre=pre->next;
        p->next=pre->next;
        pre->next=p;
        p=r;
    }
}

 

7、删除给定单链表中所有介于给定两个值之间的元素

和之前的顺序表上面的都是差不多 

void delete_st(LinkList &L,int min,int max){
//    删除给定单链表中所有介于给定两个值之间的元素
    LNode *p,*pre;
    p=L->next;
    pre=L;
    while(p!=NULL){
        if(p->data<max&&p->data>min){
            pre->next=p->next;
            free(p);
            p=pre->next;
        }
        else{      
    //注意区分和删除最小值的代码。这个有涉及在循环里面删除结点,所以不满足条件的时候才扫描下一个结点
            pre=p;
            p=p->next;
        }
    }    
}

 

 

 8、给定两个单链表,编写算法找出两个链表的公共结点

LinkList find_Common(LinkList A,LinkList B){
    LNode *p=A->next,*q=B->next;
    int dist;
    LinkList longlist,shortlist;
    int lenA=GetLength(A);
    int lenB=GetLength(B);
    if(lenA>lenB){
        longlist=A->next;shortlist=B->next;
        dist=lenA-lenB;
    }
    else{
        longlist=B->next;shortlist=A->next;
        dist=lenB-lenA;
    }
    while(dist--)longlist=longlist->next;
    while(longlist!=NULL){
        if(longlist==shortlist)return longlist;
        else{
            longlist=longlist->next;
            shortlist=shortlist->next;
        }
    }
    return NULL;
} 

 

9、按递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间。

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

 

 

 

 

 

 

 

 

10、将一个带头节点的单链表A分解为两个带头节点的单链表A和B,使得A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持其相对顺序不变。

第一种:设置访问序号变量。

void DisCreate1(LinkList &A,LinkList &B){
    B=(LinkList)malloc(sizeof(LNode));
    B->next=NULL;
    LNode *p;
    LNode *ra=A;
    LNode *rb=B;
    p=A->next;
    A->next=NULL;
    while(p!=NULL){
        rb->next=p;
        rb=p;
        ra->next=p->next;
        ra=p->next;
        p=p->next->next;
    }
    ra->next=NULL;
    rb->next=NULL;
}

第二种,不用设置序号变量,一次处理两个,第一个处理的结点就是奇数号结点,第二个处理的结点就是偶数号结点。

void DisCreate2(LinkList &A,LinkList &B){
    B=(LinkList)malloc(sizeof(LNode));
    B->next=NULL;
    int i=0;
    LNode *p;
    LNode *ra=A;
    LNode *rb=B;
    p=A->next;
    A->next=NULL;
    while(p!=NULL){
        i++;
        if(i%2==0){
            rb->next=p;
            rb=p;
        }
        else{
            ra->next=p;
            ra=p;
        }
        p=p->next;
    }
    ra->next=NULL;
    rb->next=NULL;
}

 

11、设C={a1,b1,a2,b2,……an,bn}为线性表,采用带头结点的单链表表示,设计一个就地算法将其拆分为两个线性表,分别为A={a1,a2,a3.an},和{b1,b2,b3.,,,bn}

LinkList DisCreateAB(LinkList &A){
    LinkList B=(LinkList)malloc(sizeof(LNode));
    B->next=NULL;
    LNode *p,*s;
    LNode *ra=A;
    p=A->next;
    while(p!=NULL){
            s=p->next;
            p->next=B->next;
            B->next=p;
            p=s;
            ra->next=p;
            ra=p;
            p=p->next;
    }
    ra->next=NULL;
    return B;
}

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/double891/p/9139701.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞