数据结构(王道)链表部分

数据结构(王道)链表部分习题代码实现

#include <bits/stdc++.h>

int main()
{

}
//删除所有值为x的结点
void deleteAllDataIsX(SqList &head,int x){
    Lnode *p = head->next;
    Lnode *pre = head;
    Lnode = *q;

    while(p!=null){
        if(p->data == x){
            q = p;
            p = p->next;
            pre->next = p;
            free(q);
        }
        else{
            pre  = p;
            p = p->next;
        }
    }
}

//删除一个链表中最小值节点的方法(最小值唯一)
SqList DeleteMinInList(SqList &L){
    Lnode *p = L->next;
    Lnode *pre = L;
    Lnode *min = p;
    Lnode *minpre = pre;
    while(p!=NULL){
        if(p->data<min->data){
            min = p;
            minpre = pre;
        }
        pre = p;
        p = p->next;

    }
    //到现在为止那么min则就是最小值节点的位置
    minpre->next = min->next;
    free(min);
    return L;
}

//就地逆置链表
List Reverse(SqList &L){
    Lnode *p = L->next;
    Lnode *pre;
    Lnode *right = p->next;

    p->next = NULL;
    while(right!=NULL){
        pre = p;
        p = right;
        right = right->next;
        p->next = pre;
    }
    L->next = p;
    return L;
}

//删除所有介于两个给定的值之间的方法(7)
List DeleteBetweenAB(Sqlist &L,int a,int b){
    Lnode *p = L->next;
    Lnode *pre = L;
    Lnode *q;
    while(p!=NULL){
        if(p->data>=a&&p->data<=b){
            q = p;
            pre->next = p->next;
            free(q);
        }
        else{
            pre = p;
            p = p->next;
        }
    }
    return L;
}

//算法找出两个链表的公共节点
int getLen(SqList &T){
    Lnode *p = T->next;
    int count = 0;
    while(p!=NULL){
        count++;
        p = p->next;
    }
    return count;
}
List FindParrellNode(SqList &L1,SqList &L2){
    int len1 = getLen(L1);
    int len2 = getLen(L2);
    Lnode *longList;
    Lnode *shortList;
    int chazhi;

    if(len1>len2){
        longList = L1->next;
        shortList = L2->next;
        chazhi = len1-len2;
    }
    else{
        longList = L2->next;
        shortList = L1->next;
        chazhi = len2-len1;
    }
    while(chazhi--){
        longList = longList->next;

    }
//    对齐后的操作
    while(longList!=NULL){
        if(longList==shortList){
            return longList;
        }else{
            longList = longList->next;
            shortList = shortList->next;
        }
    }
    //都没有
    return NULL;
}


//按照递增次序输出各个节点的数据元素,释放空间
void PrintNumber(SqList &L){
    Lnode *p = L->next;
    while(p!=NULL){
        Lnode *pre  = L;
        Lnode *t = pre->next;
        while(t->next!=NULL){
            if(t->next->data < pre->next->data){
                pre = t;
                t = t->next;
            }
        }
        printf(pre->next->data);
        Lnode q = pre->next;
        pre->next = q->next;
        free(q);
    }
    free(L);
}

//将一个带头结点的A分成两个链表,A存在原本序号为奇数的,B为偶数的,顺序保持不变
List CreateAnother(SqList &A){
    int number = 0;
    B = (SqList)malloc(sizeof(Lnode));
    B->next = NULL;
    Lnode *Apre = A;
    Lnode *Bpre = B;
    Lnode p = A->next;
//    Lnode q = B->next;
    A->next = NULL;
    while(p!=NULL){
        //因为带头结点嗷,所以序号和下标是不太有区别的
        number++;
        if(number%2!=0){
            Bpre->next = p;
            Bpre = p;
        }else{
            Apre->next = p;
            Apre = p;
        }
    }
    Apre->next = NULL;
    Bpre->next = NULL;
    return B;
}

//11.拆分成为两个线性表{a1,b1,a2,b2...an,bn}=>{a1,a2..,an}&{bn,..b1}

//思路和上题是一样的,也可以使用number来看奇数还是偶数,这里实际上是可以不使用的
Link Gap(SqList &A){
//    int number =0;
    B = (List)malloc(sizeof(Lnode));
    B->next = NULL;
    Lnode *p = A->next;
    Lnode *q;
    Lnode *leftA = A;
    while(p!=NULL){
        leftA->next = p;
        leftA = p;
        p = p->next;//到偶数了
        if(p!=NULL){
            q = p->next;
        }
        //头插法
        p->next = B->next;
        B->next = p;
        p = q;
    }
    leftA->next = NULL;
    return B;
}

//递增有序的线性表,数值相同的元素存在,去掉数值相同的,表中不再有重复的
List quChong(SqList &L){
    Lnode *p = L->next;
    Lnode *last ;
    if(p==NULL){
        return 0;
    }
    while(p->next!=NULL){
        last = p->next;
        if(last->data == p->data){
            p->next = last->next;
            free(last);
        }
        else{
            p=p->next;
        }
    }
    return L;
}

//两个递增的线性表,直接归并成为一个递减次序的单链表
List hebing(SqList &L1,SqList &L2){
    Lnode *p1 = L1->next;
    Lnode *p2 = L2->next;
    Lnode *p3;
    L1->next = NULL;
    while(p1&&p2){
        if(p1->data <= p2->data){
            p3 = p1->next;
            p1->next = L1->next;
            L1->next = p1;
            p1 = p3;
        }
        else{
            p3 = p2->next;
            p2->next = L1->next;
            L1->next = p2;
            p2 = p3;
        }
    }
    if(p1)
        p2=p1;
    while(p2){
        p3 = p2->next;
        p2->next = L1->next;
        L1->next = p2;
        p2 = p3;
    }
    free(L2);
}


// 设为A与B两个单链表 元素递增有序 将其里面的公共的元素产生单链表C
List generateC(Sqlist &A,Sqlist &B){
    Lnode *p1 = A->next;
    Lnode *p2 = B->next;
    List C = (List)malloc(sizeof(Lnode));
    Lnode r = C;
    while(p1!=NULL&&p2!=NULL){
        if(p1->data < p2->data){
            p1 = p1->next;
        }
        else if(p1->data<p2->data){
            p2 = p2->next;
        }
        //表示两个节点相等,表示找到了公共元素
        else{
            Lnode s = (Lnode)malloc(sizeof(Lnode));
            s->data = p1->data;
            r->next = s;
            r = s;
            p1 = p1->next;
            p2 = p2->next;
        }
    }
    r->next = NULL;
    return C;
}


// A B表示两个集合,元素递增排列,求AB的交集
//挨个对比就行,对比出来的就可以直接尾插到A之后就行,小的话肯定就继续往后看,若有一个链表已经空了,那么后面的不可能会有一样的元素了。
List jiaoji(SqList &A,SqList &B){
    Lnode *p1 = A->next;
    Lnode *p2 = B->next;
    Lnode *p3 = A;
    Lnode *u;
//    p3->next = NULL;
    while(p1&&p2){
        if(p1->data == p2->data){
            p3->next = p1;
            p3 = p1;
            u = p2;
            p2 = p2->next;
            free(u);
        }
        else if(p1->data < p2->data){
            u = p1;
            p1 = p1->next;
            free(u);
        }
        else{
            u = p2;
            p2 = p2->next;
            free(u);
        }
    }
    while(p1){
        u = p1;
        p1 = p1->next;
        free(u);
    }
    while(p2){
        u = p2;
        p2 = p2->next;
        free(u)
    }
    p3->next = NULL;//A finished
    free(p2);
    return l1;
}

// 两个整数序列 设计算法判断B是否为A的连续子序列
bool IsSmall(SqList &A,SqList &B){
//   B是A的连续子序列,那么B的长度一定小于A
    // mei tou jiedian
    Lnode *p = A;
    Lnode *pre = p;
    Lnode *q = B;
    while(p&&q){
        if(p->data == q->data){
            p = p->next;
            q = q->next;
        }
        else{
            pre = pre->next;
            p = pre; //直接下一个节点再与B开始进行比较
            q =B; //清空
        }
    }
    if(q== NULL){
        return true;
    }else{
        return false;
    }
}


//判断带头节点的链表是否对称(循环双链表)
bool IsSymmetry(SqList &L){
    Lnode *p = L->next;
    Lnode *last = L->pre;
    while(p!=last&&last->next!=p){
        if(p->data == last->data){
            p= p->next;
            last = last->pre;
        }
        else{
            return false;
        }
    }
    return true;
}

//设有一个头节点的循环单链表,找出链表最小的节点同时输出,然后删除直到链表为空
void DeleteMin(SqList &L){
    Lnode *p ,*pre , *minnp,*minpre;
    while(L->next != L) {
        p = L->next;
        pre = L;
        minp = p;
        minpre = pre;
        while (p != L) {
            if (p->data < minp->data) {
                minp = p;
                minpre = pre;
            }
            pre = pre->next;
            p = p->next;
        }

        cout << minp->data << endl;
        minpre->next = minp->next;
        free(minp);
    }
    free(L);
}


//查找链表倒数第K个位置上的节点,若查找成功,输出此位置的data
typedef struct Lnode{
    int data;
    struct Lnode *link;
}Lnode,*list;
int searchLastK(list l1,int k ){
    Lnode *p=l1->link;
    Lnode *q = l1->link;
    int number = 0;
    while(p!=NULL){
        if(number<k){
            number++;
        }else{
            q=q->link;
        }
        p=p->link;
    }
    if(number<k){
        return 0;
    }else{
        cout<<q->data<<endl;
        return 1;
    }
}
//第二种方法
typedef struct Lnode{
    int data;
    struct Lnode *link;
}Lnode,*List;
int SearchLastK(List L,int k){
    Lnode *p = L;
    Lnode *q = L;
    while(k--){
        if(q == NULL){
            return 0;
        }else{
            q = q->link;
        }
    }
    while(q!=NULL){
        q= q->link;
        p = p->link;
    }
    cout<< p->link->data <<endl;
    return 1;
}


//带头结点的单链表,若两个单词有相同的后缀,那么就找出公共后缀的起始位置
typedef struct Lnode{
    char juzi;
    struct Lnode *next;
}Snode,*Linklist;
int Length(LinkList &L){
    int count=0;
    while(p!=NULL){
        count++;
        p = p->next;
    }
    return count;
}
int mainfunction(Snode *str1,Snode *str2){
    int str1L = Length(str1);
    int str2L = Length(str2);
    Snode *l1,*l2;
    for(l1 = str1;str1L>str2L;str1L--){
        str1 = str1->next;
    }
    for(l2= str2;str2<str1L;str2L--){
        str2 = str2->next;
    }
    while(str1->next!= NULL&&str1->next!=str2->next){
        str1= str1->next;
        str2= str2->next
    }
    return str1->next;
}

//第二种笨办法
int mainfun(Snode *str1,Snode *str2){
    int len1 = Length(str1);
    int len2 = Length(str2);
    Snode *longL,*shortL;
    int chazhi;
    if(len1<len2){
        longL= str2->next;
        shortL=str1->next;
        chazhi = len2-len1;
    }
    else if(len2<len1) {
        longL = str1->next;
        shortL=str2->next;
        chazhi = len1 - len2;
    }
    while(chazhi--){
        longL = longL->next;
    }
    while(longL!=NULL){
        if(longL == shortL){
            return longL;
        }else{
            longL = longL->next;
            shortL = shortL->next;
        }
    }
    return NULL;
}


// 保存m个整数,对于链表中绝对值相等的节点,data<=n,只保留第一次出现的节点,删除其他的绝对值一样的节点
typedef struct Lnode{
    int data;
    struct Lnode *link;
}node;
void func(node head,int n){
    int a[n+1];
    for(int i= 0 ;i<n+1;i++){
        a[i] =0;
    }
    node *p=head;
    node *d;
    while(p->link!=NULL){
        //绝对值判断
        p->link->data>0?p->link->data:-(p->link->data);
        if(a[p->link->data]==0){
            a[p->link->data] = 1;
            p= p->link;
        }else{
            d = p->link;
            p->link=d->link;
            free(d);
        }
    }
    free(a);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值