王道线性表算法题

王道线性表

2.2.3顺序表

//2.2.3
typedef struct LNode{
    int data[100];
    int length;
}LinkNode,*LinkList;
//1.删min,返回值,并用最后一个元素填补
int deletemin(LinkList T,int min){
    if(L.length==0){
        printf("表空");
        return;
    }
    int min=T[0];
    int i=1;
    int count=0;
    while(i<L.length){
        if(min>L.data[i])
        {
            count=i;
            min=L.data[i++];
        }
        else
            i++;
    }
	L.data[count]=L.data[--length];
    return min;
} 

//2.空间复杂度O(1)的顺序表逆置;
void Reverse(LinkList L){
    int temp,i=0;
    for(i=0;i<L.length/2;i++){
        temp=L.data[i];
        L.data[i]=L.data[length-1-i];
        L.data[length-1-i]=temp;
    }
}
//3.长度为n的L,编写删除所有x的元素,时间复杂度O(n),空间复杂度O(1)
void DeleteAll(LinkList L,int x){
    int k=0,c=0;
    //方法1
    while(i<L.length){
        if(L.data[i]==x)
        {
            c++;
            i++;
        }
        else
            L.data[i-c]=L.data[i++];
    }
    L.length-=c;
    //方法2 记不太清了
    while(i<L.length){
        if(L.data[i]!=x){
            L.data[c]=L.data[i++];
            c++;
        }
    }
    L.length=c;
}
//4.删除有序表s-t的值(s<t),不合理时输出错误
void deleteOrder(LinkList L,int s,int t){
    if(s>t){
        printf("s,t不合法");
        return;
    }
    if(L.length==0){
        printf("表空");
        return;
    }
    int  i=0,k=0;
    while(i<L.length){
        if(L.data[i]>s){
            if(L.data[i]<t)
                k++;
            else
                L.data[i-k]=L.data[i];
        }
        i++;
    }
    L.length-=k;
}
//答案
bool Delete_s_t(LinkList L,int s,int t){
    int i,j;
    for(i=0;i<L.length;i++)
        if(L.data[i]>s)
            break;
    if(i>L.Length)
        return false;
    for(j=i;j<L.length&&L.data[j]<=t;j++);
    for(;j<L.length;j++)
        L.data[i++]=L.[j];
    L.length=i;
    return true;
}
//5.删除顺序表s-t的值(s<t),不合理时输出错误
void deleteinOrder(LinkList L,int s,int t){
    if(s>t){
        printf("s,t不合法");
        return;
    }
    if(L.length==0){
        printf("表空");
        return;
    }
    int i=0,c=0;
    while(i<L.length){
        if(L.data[i]>s && L.data[i]<t){
            c++;
        }
        else
            L.data[i-c]=L.data[i];
        i++;
    }
    L.length-=c;
}
//6.有序表删所有重复值,使表中元素都不同
bool deleteSame(LinkList L){
    //忘了输出错误
    if(L.length==0)
        return false;
    LinkList P;
    int i=0,j=0;
    for(i=1;i<L.length;i++){
        if(L.data[i]!=L.data[i-1]){
            P.data[j++]=L.data[i-1];
        }
    }
    for(int k=0;k<j;k++){
        L.data[k]=P.data[k];
    }
    L.length=j;
    return true;
    
    //答案
    for(i=0,j=1;j<L.length;j++){
        if(L.data[i]!=L.data[j]){
            L.data[++i]=L.data[j];
        }
    }
    L.length=i+1;
    return true;
}
//7.两个有序表合并
LinkNode* Combine(LinkList LA,LinkList LB){
    int i=0,j=0,temp;
    LinkNode *Lc;
    Lc.length=A+B;
    int k=0;
    if(LA.length==0 && LB.Length==0)
        return NULL;
    if(LA.length==0)
        return LB;
    if(LB.Length==0)
        return LA;
    while(i<LA.length && j<LB.length){
        if(LA.data[i]>LB.data[j])
            Lc.data[k++]=LB.data[j++];
        else 
            Lc.data[k++]=LA.data[i++];
    }
    while(i<LA.length)
        Lc.data[k++]=LA.data[i++];
    while(j<LB.length)
        Lc.data[k++]=LB.data[j++];
    Lc.length=k;//忘了
    return Lc;
}
//答案
bool Combine(LinkList LA,LinkList LB,LinkList &Lc){
    //AB表长和超过CMax
    if(LA.length+LB.Length>Lc.Maxsize)
        return false;
    
    int i=0,j=0,k=0;
    while(i<LA.length && j<LB.length){
        if(LA.data[i]>LB.data[j])
            Lc.data[k++]=LB.data[j++];
        else 
            Lc.data[k++]=LA.data[i++];
    }
    while(i<LA.length)
        Lc.data[k++]=LA.data[i++];
    while(j<LB.length)
        Lc.data[k++]=LB.data[j++];
    Lc.length=k;
    return true;
}
//8.A[m+n]中依次存放两个线性表(a1,……,an)和(b1,……,bn),调整顺序为将b1-bn-a1-an
void Reverse(LinkList A,int low,int high){
    //判误
    if(low>high)
        return ;
    int i,temp;
    for(i=low;i<=low+high/2;i++){
        temp=A.data[i];
        A.data[i]=[high-i];
        A.data[high-i]=temp;
    }
}
Reverse(A,0,n-1);
Reverse(A,n,m+n-1);
Reverse(A,0,m+n-1);

//答案
void Reverse(LinkList A,int low,int high,int arraysize){
    //判误
    if(low>high || high>arraysize)
        return ;
    int i,mid=low+high/2;
    
    for(i=0;i<=mid-low;i++){
        temp=A.data[low+i];
        A.data[low+i]=[high-i];
        A.data[high-i]=temp;
    }
}
Reverse(A,0,m+n-1,arraysize);
Reverse(A,0,n-1,arraysize);
Reverse(A,n,m+n-1,arraysize);
//9.线性表a1-an在计算机内递增有序,设计算法在最少的时间内找到值为x的元素,并与其后继元素交换位置,否则将其插入并使表仍然有序
bool Findx(LinkList L,int x){
    if(L.length==0)
        return false;
    int low=0,high=L.length-1;
    int mid;
    //for(int i=low;i<=low+high/2;i++){更正
    while(low<high){
        mid=low+high/2;
        if(x>L.data[mid])
            low=mid;//low=mid+1;
        else  if(x<L.data[mid])
            high=mid;//high=mid11;
        else{
            if(mid!=L.length-1){
                L.data[mid]=L.data[mid+1];
            	L.data[mid+1]=x;
            	return true;
            }
            }
        }
    }
    if(low>high)
        for(j=L.length-1;j>high;j--)
            L.data[j]=L.data[j-1];
            //L.data[j+1]=L.data[j]; 
    L.data[high]=x;//L.data[j+1]=x;更正
    return true;
}
//答案
void search_x(int A[],int x){
    int low=0,high=n-1,mid;
    while(low<=high){
        mid=low+high/2;
        if(x==A[mid])
            break;
        else if(x<A[mid])
            high=mid-1;
        else
            low=mid+1;
    }
    //if(mid!=n-1){//这里x不一定等于A[mid]
    if(mid!=n-1&&x==A[mid]){
        A[mid]=A[mid+1];
        A[mid]=x;
    }
    if(low>high){
        for(int j=n-1;j>high;j--)
            A[j+1]=A[j];
    	A[j+1]=x;//或者A[high+1]=x;
    }
        for(int j=n-1;j>high;j--)
            A[j+1]=A[j];
    A[j+1]=x;
}
//10.(2010统考)循环左移,数组R(X0,X1----Xn)->(Xp,Xp+1,----,Xn,X0,X1---,Xp-1)
void LeftSWIFT(int R[],int p){//辅助数组
    int A[p]for(int i=0;i<p;i++){
        A[i]=R[i];
    }
    for(int i=0;i<n-p;i++){
        R[i]=R[p+i];
    }
    int j=0;
    while(i<n)
        R[i++]=A[j++]
}//复杂度2*O(p)+O[n-p]=O[n+p]--时间O[n],空间O[p],
//答案,转换为数组ab的逆置ba
void Reverse(int A[],int left,int right){
    int mid=left+right/2;
    for(int i=0;i<=mid-left;i++){
        int temp=A[left+i];
        A[left+i]=A[right-i];
        A[right-i]=temp;
    }
    
}
Reverse(A,0,p-1);
Reverse(A,p,n-1);
Reverse(A,0,n-1);
//11.(2011真题)长度L的升序S线性表,L/2向上取整出为中位数,两个序列的中位数是他们所有升序元素的中位数,现有两个等长的A和B表,求其中位数
int midnumber(LinkList A,LinkList B){
    if(A.length==0)
        return;
    if(A.data[length-1]>=B.data[0])
        return B.data[length-1];
    if(B.data[length-1]>=A.data[0])
        return A.data[length-1];
    int i=0,j=0,count=0;
    while(count<=A.length){
        if(A.data[i]>B.data[j])
            j++;
        else
            i++;
        count++;
    }
    if(A.data[i]<B.data[j])
        return A.data[i];
    else
        return B.data[j];
}//时间复杂度O[n],空间O[1];
//答案:根据A和B中位数的大小比较
//a=b,直接求得。a<b,舍弃A小一半和B中大一半,a>b反之
int midNumber(LinkList A,LinkList B){
    int s1=0,t1=n-1,s2=0,t2=n-1,m1,m2;
    while(s1!=d1 || s2!=d2){
        m1=s1+d1/2;
        m2=s2+d2/2;
        if(A[m1]==B[m2])
            return A[m1];
        else
            if(A[m1]>b[m2]){
                if((s2+d2)%2==0){
                    d1=m1;
                    s2=m2;
                }
                else{
                    d1=m1;
                    s2=m2+1;
                }
                
            }
        else{
            if((s1+d1)%2==0){
                    d2=m2;
                    s2=m1;
                }
                else{
                    d2=m2;
                    s1=m1+1;
                }
        }
    }
    return A[s1]<B[s2]?A[s1]:B[s2];
}//时间复杂度O(logn),空间O[1]

//12.寻找数组A[n]中的主元素,有超过长度n/2就是主元素
int FoundMain(int A[]){
    int i=0;
    int count[];
    for(i=0;i<n;i++){
        count[i]=0;
        for(int j=1;j<n;j++){
            if(A[i]==A[j])
                count[i]++;
        }
    }
    int flag=0;
    while(i<n){
        if(count[i]<n/2)
            flag++;
        else
            return A[i];
    }
    if(flag==n)
        return -1;
}//时间复杂度O(n2),空间O(n)

//答案:从前向后扫描数组元素,标记可能为主元素的Num,然后重新计数,确认Num是否为主元素,再进行更新
int Majority(int A[],int n){
    int count=1,i=0,c;
    c=A[0];
    for(i=1;i<n;i++){
        if(A[i]==c)
            count++;
        else{
            if(count>0)
                count--;
            else{
                c=A[i];
                count=1;
            }
        }
    }
    if(count>0)
        for(i=count=0;i<n;i++)
            if(A[i]==c)
                count++;
    if(count>n/2)
        return c;
    return -1;
}//时间复杂度O(n),空间复杂度O(1)
//13.找数组中未出现的最小正整数
int FoundMin(int A[], int n) {
    int num = 1;
    int i = 0;
    for (i = 0; i < n; i++) {
        if (A[i] > 0) {
            if (A[i] == num) {
                num++;
            }
        }
    }
    return num;
}//时间复杂度O(n),空间O(1),有错,例如5,3,2,1,3,4,-1,min=2,但是2在前面出现过
int FoundMin(int A[], int n) {//更正版
    int num = 1;
    int i = 0;
    for (i = 0; i < n; i++) {
        if (A[i] > 0) {
            if (A[i] == num) {
                num++;
                FoundMin(A, i);
            }
        }
    }
    if (num == A[0])
        num++;
    return num;
}//最坏时间复杂度O(n!),空间O(1)
//答案,使用B数组记录1-n是否存在;
int FoundMin(int A[]){
    int num=1,*B;
    B=(int *)malloc(sizeof(int)*n);
    int i=0,j=0;
    memset(B,0,sizeof(int)*n);
    for(i=0;i<n;i++){
        if(A[i]>0&&A[i]<=n){
            B[A[i]-1]=1;
        }   
    }
    for(j=0;j<n;j++){
        if(B[j]!=1)
            break;
    }
    return j+1;
}//时间复杂度O(n),空间O(1)
//14.三元组(a,b,c)均为正数的距离D为|a-b|+|b-c|+|c-a|,给定3个非空整数集S1,S2,S3,按照升序分别存储三个数组。设计算法,计算并输出所有三元组(a,b,c)(a@S1,b@S2,c@S3)中的最小距离
//例如S1{-1,0,9},S2{-25,-10,10,11},S3{2,9,17,30,41},则最小距离为2,{9,10,9}
思想描述,分别找三个数组的中位数,0-10,17,-->0,10,9,-->9,10,9
int n1,n2,n3;
int mid[3];
void FindMinDistance(int S1[],int S2[],int S3[]){
    mid[0]=FindMid(S1[],n1);
    mid[1]=FindMid(S2[],n2);
    mid[2]=FindMid(S3[],n3);
    if(mid[0]>mid[1]&&mid[0]<mid[2]){
        
    }
    
}
int FindMax_Min(int S[]){
    if(S[0]>S[1]&&S[0]<S[2])
        return 
}
int FindMid(int Num[],int length){
    int low=0,high=length-1,mid;
    mid=low+high/2;
    return Num[mid];
    for(int i=low;i<=low+high/2;i++){
        mid=low+high/2;
        if()
    }
}

//答案思路,D=|a-b|+|b-c|+|c-a|=2|c-a|,每次固定一个c找a,使得|c-a|最小
#define INT_MAX 0x7fffffff
int abs_(int a){//计算绝对值
    if(a<0) return -a;
    return a;
}
bool xIs_min(int a,int b,int c){//判断是否是三个中最小
    if(a<b&&a<c) return true;
	return false;
}
int FindMinOfTrip(int A[],int n,int B[],int m,int C[],int p){
    int i=0,j=0,k=0,D_min=INT_MAX;
    while(i<n&&j<m&&k<p&&D_min>0){
        D=abs_(A[i]-B[j])+abs_(B[j]-C[k])+abs_(C[k]-A[i]);
        if(D<D_min) D_min=D;
        if(xls_min(A[i],B[j],C[k])) i++;
        else if(xls_min(B[j],A[i],C[k]))
            j++;
        else
            k++;
    }
    return D_min;
}//N=m+n+p时间复杂度为O(N),空间为O(1);

2.3.7链表

typedef struct LinkNode{
    int data;
    struct LinkNode *next;
}LinkNode,*LinkList;
//1.递归算法,删除不带头结点的链表中所有x值的结点
void Delete_x(LinkList &L,int x){
    if(L==NULL)
        return;
    if(L->data==x){
        LinkNode *s;
        s=L;
        L=s->next;
        free(s);
    }
    else
        Delete_x(L->next,x);
}
//2.带头结点的单链表L中,删除所有值为x的结点,并释放其空间,假设值为x的结点不唯一
void Delete_x(LinkList &L,int x){
    LinkNode *p;
    p=L;
    while(p->next!=NULL){
        if(p->next->data==x){
            LinkNode *q=p->next;
            p->next=q->next;
            free(q);
        }
        p=p->next;
    }
}

//答案1,思想同上
void delete_x1(LinkList &L,int x){//无序链表删除,删指定范围元素
    LinkNode *p=L->next,*pre=L,*q;
    while(p!=NULL){
        if(p->data==x){
            q=p;
            p=p->next;
            pre->next=p;
            free(q);
        }
        else{
            pre=p;
            p=p->next;
        }
    }
}
//答案2
void delete_x2(LinkList &L,int x){
    LinkNode *p=L->next,*r=L,*q;
    while(p!=NULL){
        if(p->data!=x){
            r->next=p;
            r=p;
            p=p->next;
        }
        else{
            q=p;
            p=p->next;
            free(q);
        }
    }
    r->next=NULL;
}
//3.带头结点L,逆序反向输出链表
void OutPut(LinkList L){
    LinkNode *p=L->next;
    while(p!=NULL){
        if(p->next==NULL)
            printf("%d",p->data);
        else
        	printf("%d->",p->data);
    }
}
int GetLength(LinkList L){
    int i=0;
    while(L->next!=NULL){
        i++;
        L=L->next;
    }
    return i;
}
void ReverseOutput(LinkList L){//头插法
    LinkNode *p,*N;
    if(L==NULL)
        return ;
    p=L->next;
    if(p->next==NULL){
        printf("%d",p->data);
    }
    while(p!=NULL){
        LinkNode *s=p;
        s->next=N->next;
        N->next=s;
        p=p->next;
    }
    OutPut(N);
}

void ReverseOutput(LinkList L){//数组
    LinkNode *p;
    p=L->next;
    Length=GetLength(L);
    if(Length==0)
        return;
    int *B,i=0;
    B=(int *)malloc(sizeof(int)*Length);
    while(p!=NULL){
        B[length-i-1]=p->data;
        p=p->next;
    }
    int j;
    while(j<Length){
        if(j+1==Length)
            printf("%d",B[j]);
        else
        	printf("%d->",B[j]);
    }
}

//答案--栈
void R_Print(LinkList L){
    if(L->next!=NULL)
        R_Print(L->next);
    if(L!=NULL)
        print(L->data); 
}
void R_Ignore_head(LinkList L){
    if(L->next!=NULL)
        R_Print(L->next);
}
//4.删除链表最小值结点的高效算法,假设最小值唯一
int Delete_Min(LinkList L){
    int min;
    LinkList *p;
    p=L->next;
    if(p==NULL)
        return ;
    min=p->data;
    while(p->next!=NULL){
        if(p->next->data<min)
            min=p->next->data;
    }
    return min;
}
LinkList DeleteMIN(LinkList &L){
    LinkNode *pre=L,*p=pre->next;
   	LinkNode *minp=p,*minpre=pre;
    while(p!=NULL){
        if(p->data<minp->data){
            minp=p;
            minpre=pre;
        }
        pre=p;
        p=p->next;
    }
    minpre->next=minp->next;
    free(minp);
    return L;
}
//5.就地逆置单链表,空间复杂度O(1)
void ReverseList(LinkList &L){//没想完
    Length=GetLength(L);
    LinkList *p=L->next;
    if(p==NULL|| p->next==NULL)
        return;
    int i=0;
    while(p!=NULL){
        int temp=Getdata[length-1-i];
        p->data
    }
}
void ReverseList(LinkList &L){
    LinkList *p=L->next;
    if(p==NULL|| p->next==NULL)
        return;
    L->next=NULL;
    while(p!=NULL){
        LinkNode *s=p;
        p=s->next;
        s->next=L->next;
        L->next=s;
    }
}
//答案-链表指针逆向
void Reverse2(LinkList &L){
    LinkNode *pre,*p=L->next;*r=p->next;
    p->next=NULL;
    while(r!=NULL){
        pre=p;
        p=r;
        r=r->next;
        p->next=pre;
    }
    L->next=p;
}

//6.一个带头结点的链表,使其递增有序
void AscendOrder(LinkList &L){
    LinkNode *p;
    p=L->next;
    L->next=NULL;
    Length=GetLength(L);
    if(Length==0||Length==1)
        return ;
    int min[Length];
    int i=0;
    while(p!=NULL){
        min[i++]=p->data;
        p=p->next;
    }
    for(int j=0;j<Length;j++){
        for(int k=1;k<Length;k++){
            if(min[j]<min[k]){
                int temp=min[j];
                min[j]=min[k];
                min[k]=min[j];
            }
        }
    }
    k=0;
    while(k<Length){
        LinkNode *q;
        q->data=min[k++];
        q->next=L->next;
        L->next=q;
    }
}
//答案
void Sort(LinkList &L){
    LinkNode *p=L->next,*pre;
    LinkNode *r=p->next;
    p->next=NULL;						//构建新的有序表
    p=r;
    while(p!=NULL){
        r=p->next;						//保存*p后继结点
        pre=L;
        while(pre->next!=NULL&&pre->next->data<p->data)
            pre=pre->next;				//找到有序表结点的前驱
        p->next=pre->next;
        pre->next=p;
        p=r;
    }
}
//7.无序带头结点链表,删除介于s和t之间结点
void delete_s_t(LinkList &L,int s,int t){
    if(s>t)
        return;
    LinkNode *p;
    p=L;
    if(p->next==NULL)
        return;
    while(p->next!=NULL){
        if(p->next->data>s&&p->next->data<=t){
            LinkNode *q=p->next;
            p->next=q->next;
            free(q);
        }
        p=p->next;
    }
}
//8.找出两个链表的公共结点
void FindSame(LinkList &La,LinkList Lb){
    L1=GetLength(La);
    L2=GetLength(Lb);
    LinkNode *p1,*p2;
    p1=La->next;
    p2=Lb->next;
    while(p1!=NULL){
            int flag=0;
            while(p2!=NULL){
                if(p2->data==p1->data){
                	flag=1;
                    break;
                }
                else
                    p2=p2->next;
            }
            if(flag==1)
                p1=p1->next;
            else{
                LinkNode *s=p1;
                p1=p1->next;
                free(s);
            }  
        }
}
//答案
LNode* Public(LinkList L1, LinkList L2) {//2.3.7.08
    int len1 = GetLength(L1);
    int len2 = GetLength(L2);
    if (len1 == 0 || len2 == 0)
        return NULL;
    if (len1 > len2) {
        int i=0;
        while (i < len1 - len2) {
            L1 = L1->next;
            i++;
        }
    }
    else {
        int i = 0;
        while (i < len1 - len2) {
            L2 = L2->next;
            i++;
        }
    }
    while (L1!=NULL) {
        if(L1==L2)
            return L1;
        else {
            L1 = L1->next;
            L2 = L2->next;
        }
    }
    return NULL;
}
//9.一个带头结点的单链表,指定头结点是head,(data,next)结构,要求按照递增顺序输出各个结点的数据并释放结点所占存储空间
void AscendOutput(LinkList &head) {//2.3.7.09
    LNode* PA = head->next, * prea = head;
    while (PA != NULL) {
        LNode* p = PA, * pre = prea;
        LNode* minp = PA, * minpre = prea;
        while (p != NULL) {
            if (minp->data > p->data) {
                minp = p;
                minpre = pre;
            }
            pre = p;
            p = p->next;
        }
        print(minp->next);
        LNode* s = minp;
        minpre->next = s->next;
        free(s);
    }
    free(head);
}
//答案
void Min_Delete(LinkList &head){
    while(head->next!=NULL){
        LinkNode *p=head->next,*pre=head;
        while(p!=NULL){
            if(p->next->data<pre->next->data)
                pre=p;
            p=p->next;
        }
        print(pre->next);
        LinkNode *s=pre->next;
        pre->next=s->next;
        free(s);
    }
    free(head);
}
//10.分解A链表为,A,B两个,A奇数,B偶数
void DividedList(LinkList &A,LinkList &B){
    LinkNode *p=A->next,*pre=A,*pb=B;
    while(p!=NULL){
        if(p->data%2==0){
            pre->next=p->next;
            p->next=pb->next;
            pb->next=p;
            p=pre->next;
            pb=pb->next;
        }
        pre=p;
        p=p->next;
    }
}
//11.C{a1,b1,a2,b2.......,an,bn},使用带头结点的hc存放,将c拆分为A{a1,.....,an},B两个表
void Divided_C(LinkList hc,LinkList &A,LinkList &B){
    LinkNode *pc=hc->next,*pa=A,*pb=B;
    int i=1;
    while(pc!=NULL){
        LinkNode *s=pc;
        pc=pc->next;
        if(i%2==1){
            s->next=pa->next;
            pa->next=s;
            pa=s;
        }
        else{
            s->next=pb->next;
            pb->next=s;
            pb=s;
        }
        i++;
    }
}
//12.递增有序链表去重
void DeleteSame(LinkList L){
    LinkNode* p=L->next,*pre=L;
    while(p!=NULL&&p->next!=NULL){
        if(p->data==p->next->data){
            pre=p;
            p=p->next->next;
        }
        else{
            pre=p;
            p=p->next;
        }
    }
}
//13.合并两个递增链表为递减链表,要求归并原来两个链表结点
void CombineDscend(LinkList &A,LinkList &B){
    LinkNode *pa=A->next,*pb=B->next,*r;
    A->next=NULL;
    while(pa!=NULL&&pb!=NULL){
        if(pa->data<pb->data){
            r=pa->next;
            pa->next=A->next;
            A->next=pa;
            pa=r;
        }
        else{
            r=pb->next;
            pb->next=A->next;
            A->next=pb;
            pb=r;
        }
    }
    while(pa!=NULL){
        r=pa->next;
        pa->next=A->next;
        A->next=pa;
        pa=r;
    }
    while(pb!=NULL){
        r=pb->next;
        pb->next=A->next;
        A->next=pb;
        pb=r;
    }
    //忘记free空表
    free(pb);
}
//14.A,B两个单链表带头结点,递增有序,设计算法获取A,B公共结点组成C表,要求不破坏A,B表
void FindSameToC(LinkList &lc,LinkList A,LinkList B){
    LinkNode *pa=A->next,*pb=B->next,*pc=lc;
    while(pa!=NULL&&pb!=NULL){
        if(pa->data==pb->data){
            LinkNode *s;
            s->data=pa->data;
            s->next=pc->next;
            pc->next=s;
            pb=pb->next;
            }
       else{
           if(pa->data>pb->data)
               pb=pb->next;
           else
               pa=pa->next;
       }
    }
}
//15.A,B两个链表表示两个集合,递增排序,求A,B交集存于A中
void FindSame3(LinkList &A,LinkList B){
    LinkNode *pa=A->next,*pb=B->next,*pc=lc,*p=A;
    A->next=NULL;
    while(pa!=NULL&&pb!=NULL){
        if(pa->data==pb->data){
            LinkNode *s=pa,*r=pa->next;
            s->next=p->next;
            p->next=s;
            p=s;
            pa=r;
            pb=pb->next;
            }
       else{
           if(pa->data>pb->data)
               pb=pb->next;
           else
               pa=pa->next;
       }
    }
}
//16.判断B是否是A的子序列
bool Is_child(LinkList A,LinkList B){
    LinkNode *pa=A->next,*pb=B->next;
    int flag=0;
    while(pa && pb){
        if(pa->data!=pb->data)
            pa=pa->data;
        else{
            flag++;
            pa=pa->next;
            pb=pb->next;
        }
    }
    int l=GetLength(B);
    if(flag==l)
        return true;
    else
        return false;
}
//17.设计算法判断带头结点的循环双链表是否对称
typedef struct DNode{
    int data;
    struct DNode* pre;
    struct DNode* next;
}Dnode,*Dlink;
bool Is_Symtem(Dlink A){//2.3.7.17,与答案相同的思路
    DNode *p=A->next,*pre=A->pre;
    int i=0;count=0;
    if(p=pre)
        return ;
    while(p->next!=pre&& p!=pre){
        if(p->data==pre->data){
            p=p->next;
            pre=pre->pre;
        }
        else
            return false
    }
    return true;
}
int Is_SymDNode(DinkList L) {//2.3.7.17
    DNode* pre=L->pre,*red=L->next;
    if (L->next == L)
        return;
    while (pre!=L && red) {
        if (pre->data == red->data) {
            pre = pre->pre;
            red = red->next;       
        }
        else {
            return -1;
        }
    }
    return 1;
}
//18.两个循环单链表,h1,h2,将h2链接在h1之后,要求链接后仍然是循环的
void Combine(LinkList &h1,LinkList h2){
    LinkNode *p1=h1->next,*p2=h2->next;
    while(p1!=h1)
        p1=p1->next;
    while(p2!=h2)
        p2=p2->next;
    p1->next=h2->next;
    p2->next=h1;
    free(h2);
}
//19.带头结点的单循环链表,逐个找到最小元素输出,并删除结点,直到表空,删除表头
void deleteMin(LinkList &L){//借鉴9的答案思想
    LinkList *p=L->next,*pre=L;
    int min;
    while(L->next!=L){
        LinkList *p=L->next,*pre=L;
        while(p->next!=L){
            if(pre->next->data>p->next->data)
                pre=p;
            p=p->next;
        }
        print(pre->next->data);
        LinkNode *u=pre->next;
        pre->next=u->next;
        free(u)
    }
    free(L);
}
//20.非循环双链表,pre,next,data,访问频度fred(初始化为0),每次located(L,x)运算,fred+1,同时结点按照频度递减顺序排列,最近访问的排在频度相同的前面,编写满足要求的Located()
LinkNode* Located(LinkList L,int x){
    LinkList *p=L->next,*s;
    while(p!=NULL){
        if(p->data==x)
            break;
    }
    if(p->data==x){
        p->fred++;
        *s=p;
        p=p->pre;
        while(p!=L){
            if(p->fred>s->fred){
                s->pre->next=s->next;
                s->next->pre=s->pre;
                p->next->pre=s;
                s->next=p->next;
                p->next=s;
                s->pre=p;
            }
            else{
                p=p->pre;
            }
        }
        if(p==L){
            s->pre->next=s->next;
            s->next->pre=s->pre;
        	L->next->pre=s;
            s->next=L->next;
            L->next=s;
            s->pre=L;
        }
    }
    return s;
}
//21.判断单链表是否存在环,没完全想出来
LinkList Is_Circuit(LinkList L){
    LinkNode *SL=L,*FA=L->next->next;
    while(FA&&FA->next){
        if(SL->data==FA->data)
            break;
        else{
            SL=SL->next;
            FA=FA->next->next;
        }
    }
	if(SL==NULL|| FA==NULL)
        return NULL;
    LinkNode *p=L,*p1=SL;//L+i=r,r-i=L;L处就是入口点
	while(p!=p1){
		p=p->next;
		p1=p1->next;
	}
	return p;
}
//22.09真题,查找链表倒数第k个元素
int Find_repK(LinkList list, int x,int k) {
    int length = GetLength(list);
    int i = 0;
    LNode* p = list->next;
    if (k > length||k<1||length==0)
        return 0;
    while (i < length - k) {
        p = p->next;
    }
    x = p->data;
    return 1;
}
//23.12真题,找共同部分的结点头
LNode* FindNode(LinkList A, LinkList B) {
    LNode* pa = A->next, * pb = B->next;
    int l1 = GetLength(A), l2 = GetLength(B);
    int i = 0;
    if (l1 == 0 || l2 == 0)
        return NULL;
    if (l1 > l2) {
        while (i < l1 - l2) 
            pa = pa->next;
    }
    else
        while (i < l2 - l1)
            pb = pb->next;
    while (pa != NULL) {
        if (pa == pb)
            break;
        else {
            pa = pa->next;
            pb = pb->next;
        }
    }
    if (pa)
        return pa;
    else
        return NULL;
}
//24.15考题,删除绝对值相等的结点,除了第一个出现的
int fabs(int i) {
    if (i < 0)
        return -i;
    return i;
}
#define N 0xffffff
void DeleteFabs(LinkList L,int n) {
    int length = GetLength(L),i=0;
    //int data[N]=0;
    int* data;
    data = (int*)malloc(sizeof(int) * (n + 1));
    for (int i = 0; i < n + 1; i++) {
        data[i] = 0;
    }
    LNode* p = L->next,*pre=p;
    while (p != NULL) {
        int temp = fabs(p->data);
        if (data[temp] == 0){
            data[temp] == 1;
            pre = p;
            p = p->next;
        }
        else {
            LNode* s = p;
            pre->next = s->next;
            free(s);
            p = pre->next;
        }
    }
    //忘记freedata
    free(data);
}
//25.19统考,设计空间复杂度O(1),且时间较高效的算法,重排(a1,a2,a3....,an-1,an)为(a1,an,a2,an-2....)
LNode* ReOrder(LinkList L) {//没想完
    LNode* p = L->next, *pre,* r=p->next;
    //p->next = NULL;
    while (p != r&& p->next!=r) {
        pre = p;
        while (pre->next != r) {
            pre = pre->next;
        }
        pre->next = r->next;
        r->next = p->next;
        p->next = r;
        p = r->next;
        r = pre;

    }
    return L;
}
LinkNode* fun(LinkList L)//上面的补充完善
{
    LinkNode* j = L->next, * i = L->next, * r = L, * q = i->next;
    if (!i)
        return NULL;
    while (j)
        j = j->next; //使j成为尾指针
    if (!q)
        return NULL;
    while(i->next != j || i->next->next != j) {
        //链表长为偶数和奇数的情况
        while (r->next != j) r = r->next; //使r一直为尾指针j的前驱
        
        j->next = q; //下面为尾插和保存其他指针的代码
        i->next = j;
        j = r;
        r = L;
        i = q;
        q = q->next;
    }
    return L;
}
//答案
LNode* Change_list(LinkList L) {
    LNode* p, * q, * r, * s;
    p = q = L;
    if (!q)
        return NULL;
    while (q->next != NULL) {
        p = p->next;
        q = q->next;
        if (q->next != NULL) q = q->next;
    }
    q = p->next;
    p->next = NULL;
    while (q != NULL) {
        r = q->next;
        q->next = p->next;
        p->next = q;
        q = r;
    }
    s = L->next;
    q = p->next;
    p->next = NULL;
    while (s != NULL) {
        r = q->next;
        q->next = s->next;
        s->next = q;
        s = q->next;
        q = r;
    }
    return L;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Challfate

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

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

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

打赏作者

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

抵扣说明:

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

余额充值