zoukankan      html  css  js  c++  java
  • 链表--部分知识点整理

    1、建立单链表:

    下面两种方法的时间复杂度都是O(n)

    (1)头插法

    Linklist CreateFromHead(){
    	LinkList L;
    	LNode *s;
    	int x;
    	int flag=1;
    	L=(Linklist)malloc(sizeof(LNode));
    	L->next=NULL;
    	scanf("%d",&x);
    	while(x!=-1){
            s=(LNode*)malloc(sizeof(LNode));
            s->data=x;
            s->next=L->next;
            L->next=s;
            scanf("%d",&x);
    	}
        return L;
    }
    

    每次都相当于在头结点后面插入新元素

    (2)尾插法

    Linklist CreateFromTail(){
        LinkList L;
        LNode *r,*s;
        int x;
        L=(LNode *)malloc(sizeof(LNode));
        L->next=NULL;
        r=H;//指向头结点
        scanf("%d",&x);
        while(x!=-1){
            s=(LNode*)malloc(sizeof(LNode));
            s->data=x;
            s->next=r->next;
            r->next=s;
            r=s;
            scanf("%d",&x);
        }
        r->next=NULL;
        return L;
    }
    

    有一个尾指针r始终指向最后一个节点

    2、循环列表

    举个例子:有两个带头结点的循环单链表LA、LB,编写一个算法,将两个循环单链表合并为一个循环单链表,其头指针为LA

    分析:

    第一种情况,先找到两个链表的尾,分别用指针p、q指向它们,然后将第一个链表的尾与第二个链表的第一个结点链接起来,并修改第二个链表的尾节点,使它的链域指向第一个链表的头结点,并且释放第二个链表的头结点

    LinkList merge_1(LinkList LA,LinkList LB){
        LNode *p,*q;
        p=LA;
        q=LB;
        while(p->next!=LA)
            p=p->next;
        while(q->next!=LB)
            q=q->next;
        p->next=LB->next;
        free(LB);
        q->next=LA;
        return(LA);
    }
    

    时间复杂度为O(n)

    第二种情况,当上面的两个循环链表带有尾指针时,又怎么合并呢?

    LinkList merge_2(LinkList RA,LinkList RB)
    {
        LNode *p;
        p=RA->next;
        RA->next=RB->next->next;
        free(RB->next);
        RB->next=p;
        return(RB);
    }
    

    时间复杂度为O(1)

    循环链表实现约瑟夫环

    约瑟夫环问题,是一个经典的循环链表问题,题意是:已知 n 个人(分别用编号 1,2,3,…,n 表示)围坐在一张圆桌周围,从编号为 k 的人开始顺时针报数,数到 m 的那个人出列;他的下一个人又从 1 开始,还是顺时针开始报数,数到 m 的那个人又出列;依次重复下去,直到圆桌上剩余一个人。

    如图所示,假设此时圆周周围有 5 个人,要求从编号为 3 的人开始顺时针数数,数到 2 的那个人出列:

    出列顺序依次为:

    • 编号为 3 的人开始数 1,然后 4 数 2,所以 4 先出列;
    • 4 出列后,从 5 开始数 1,1 数 2,所以 1 出列;
    • 1 出列后,从 2 开始数 1,3 数 2,所以 3 出列;
    • 3 出列后,从 5 开始数 1,2 数 2,所以 2 出列;
    • 最后只剩下 5 自己,所以 5 胜出。

    约瑟夫环问题有多种变形,比如顺时针转改为逆时针等,虽然问题的细节有多种变数,但解决问题的中心思想是一样的,即使用循环链表。

    #include <stdio.h>
    #include <stdlib.h>
    typedef struct node{
        int number;
        struct node * next;
    }person;
    person * initLink(int n){
        person * head=(person*)malloc(sizeof(person));
        head->number=1;
        head->next=NULL;
        person * cyclic=head;
        for (int i=2; i<=n; i++) {
            person * body=(person*)malloc(sizeof(person));
            body->number=i;
            body->next=NULL; 
            cyclic->next=body;
            cyclic=cyclic->next;
        }
        cyclic->next=head;//首尾相连
        return head;
    }
    void findAndKillK(person * head,int k,int m){
        person * tail=head;
        //找到链表第一个结点的上一个结点,为删除操作做准备
        while (tail->next!=head) {
            tail=tail->next;
        }
        person * p=head;
        //找到编号为k的人
        while (p->number!=k) {
            tail=p;
            p=p->next;
        }
        //从编号为k的人开始,只有符合p->next==p时,说明链表中除了p结点,所有编号都出列了,
        while (p->next!=p) {
            //找到从p报数1开始,报m的人,并且还要知道数m-1de人的位置tail,方便做删除操作。
            for (int i=1; i<m; i++) {
                tail=p;
                p=p->next;
            }
            tail->next=p->next;//从链表上将p结点摘下来
            printf("出列人的编号为:%d
    ",p->number);
            free(p);
            p=tail->next;//继续使用p指针指向出列编号的下一个编号,游戏继续
        }
        printf("出列人的编号为:%d
    ",p->number);
        free(p);
    }
    int main() {
        printf("输入圆桌上的人数n:");
        int n;
        scanf("%d",&n);
        person * head=initLink(n);
        printf("从第k人开始报数(k>1且k<%d):",n);
        int k;
        scanf("%d",&k);
        printf("数到m的人出列:");
        int m;
        scanf("%d",&m);
        findAndKillK(head, k, m);
        return 0;
    }
    

    3、双向链表

    更方便的获得一个结点的前驱和后继结点,方便插入和删除

    在单链表的每个结点里再增加一个指向其前驱的指针域prior

    #include <stdio.h>
    #include <stdlib.h>
    typedef struct dList{
        struct dList * prior;
        int data;
        struct dList * next;
    }dList;
    //双链表的创建
    dList* initdList(dList * head);
    //双链表插入元素,add表示插入位置
    dList * insertdList(dList * head,int data,int add);
    //双链表删除指定元素
    dList * deldList(dList * head,int data);
    //双链表中查找指定元素
    int selectElem(dList * head,int elem);
    //双链表中更改指定位置节点中存储的数据,add表示更改位置
    dList *amendElem(dList * p,int add,int newElem);
    //输出双链表的实现函数
    void display(dList *head);
    int main() {
        dList *head=NULL;
        //创建双链表
        head=initdList(head);
        display(head);
        //在表中第 3 的位置插入元素 7
        head=insertdList(head, 7, 3);
        display(head);
        //表中删除元素 2
        head=deldList(head, 2);
        display(head);
        printf("元素 3 的位置是:%d
    ",selectElem(head,3));
        //表中第 3 个节点中的数据改为存储 6
        head = amendElem(head,3,6);
        display(head);
        return 0;
    }
    dList* initdList(dList * head){
        head=(dList*)malloc(sizeof(dList));
        head->prior=NULL;
        head->next=NULL;
        head->data=1;
        int i;
        dList * list=head;
        for (i=2;i<=5;i++) {
            dList *body=(dList*)malloc(sizeof(dList));
            body->prior=NULL;
            body->next=NULL;
            body->data=i;
            list->next=body;
            body->prior=list;
            list=list->next;
        }
        return head;
    }
    dList *insertdList(dList *head,int data,int add){
        int i;
        //新建数据域为data的结点
        dList *temp=(dList*)malloc(sizeof(dList));
        temp->data=data;
        temp->prior=NULL;
        temp->next=NULL;
        //插入到链表头,要特殊考虑
        if (add==1) {
            temp->next=head;
            head->prior=temp;
            head=temp;
        }else{
            dList * body=head;
            //找到要插入位置的前一个结点
            for (i=1; i<add-1; i++) {
                body=body->next;
            }
            //判断条件为真,说明插入位置为链表尾
            if (body->next==NULL) {
                body->next=temp;
                temp->prior=body;
            }else{
                body->next->prior=temp;
                temp->next=body->next;
                body->next=temp;
                temp->prior=body;
            }
        }
        return head;
    }
    dList *deldList(dList * head,int data){
        dList *temp=head;
        //遍历链表
        while (temp) {
            //判断当前结点中数据域和data是否相等,若相等,摘除该结点
            if (temp->data==data) {
                temp->prior->next=temp->next;
                temp->next->prior=temp->prior;
                free(temp);
                return head;
            }
            temp=temp->next;
        }
        printf("链表中无该数据元素");
        return head;
    }
    //head为原双链表,elem表示被查找元素
    int selectElem(dList * head,int elem){
    //新建一个指针t,初始化为头指针 head
        dList * t=head;
        int i=1;
        while (t) {
            if (t->data==elem) {
                return i;
            }
            i++;
            t=t->next;
        }
        //程序执行至此处,表示查找失败
        return -1;
    }
    //更新函数,其中,add 表示更改结点在双链表中的位置,newElem 为新数据的值
    dList *amendElem(dList * p,int add,int newElem){
        dList * temp=p;
        int i;
        //遍历到被删除结点
        for (i=1; i<add; i++) {
            temp=temp->next;
        }
        temp->data=newElem;
        return p;
    }
    //输出链表的功能函数
    void display(dList * head){
        dList * temp=head;
        while (temp) {
            if (temp->next==NULL) {
                printf("%d
    ",temp->data);
            }else{
                printf("%d->",temp->data);
            }
            temp=temp->next;
        }
    }
    

    4、线性表实现一元多项式的表示和加减乘运算

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <malloc.h>  
      
    typedef struct polyn  
    {  
        float coef;  
        int expn;  
        struct polyn* next;  
    }PolyNode,*PLinkList;  
      
    PLinkList CreatePolyn();//创建一元多项式,使一元多项式呈指数递减  
    void OutPut(PLinkList head);//输出一元多项式  
    PLinkList Addition(PLinkList L1,PLinkList L2);//多项式的加法  
    PLinkList Subtraction(PLinkList L1,PLinkList L2);//多项式的减法  
    PLinkList Reverse(PLinkList head);//将生成的链表逆置。使一元多项式呈指数递增形式  
    PLinkList MultiplyPolyn(PLinkList L1,PLinkList L2);//多项式的乘法 
    
    
    PLinkList CreatePolyn()//创建一元多项式。使一元多项式呈指数递减  
    {  
        PolyNode *p,*q,*s;  
        PolyNode *head = NULL;  
        int expn2;  
        float coef2;  
        head = (PLinkList)malloc(sizeof(PolyNode));//动态生成头结点  
        if(!head)  
        {  
            return NULL;  
        }  
        head->coef = 0.0;//初始化  
        head->expn = 0;  
        head->next = NULL;  
        do  
        {
            printf("输入系数coef(系数和指数都为0结束)");  
            scanf("%f",&coef2);  
            printf("输入指数数exp(系数和指数都为0结束)");  
            scanf("%d",&expn2);  
            if((long)coef2 == 0 && expn2 == 0)  
            {  
                break;  
            }  
            s = (PLinkList)malloc(sizeof(PolyNode));  
            if(!s)  
            {  
                return NULL;  
            }  
            s->expn = expn2;  
            s->coef = coef2;  
            q = head->next ;  
            p = head;  
            while(q && expn2 < q->expn)  
            {  
                p = q;  
                q = q->next ;  
            }  
            if(q == NULL || expn2 > q->expn)  
            {  
                p->next = s;  
                s->next = q;  
            }  
            else  
            {  
                q->coef += coef2;  
            }  
        }while(1);  
        return head;  
    }  
      
    void OutPut(PLinkList head)//输出一元多项式  
    {  
        PolyNode *p = head->next ;  
        while(p)  
        {  
            printf("%1.1f",p->coef);  
            if(p->expn)  
            {  
                printf("*x^%d",p->expn);  
            }  
            if(p->next && p->next->coef > 0)  
            {  
                printf("+");  
            }  
            p = p->next ;  
        }  
    }  
      
    PolyNode *Addition(PLinkList L1,PLinkList L2)//多项式的加法  
    {  
        PolyNode *pa,*pb,*pc,*u,*head;  
        head = (PLinkList)malloc(sizeof(PolyNode));  
        if(!head)  
        {  
            return NULL;  
        }  
        head->coef = 0.0;  
        head->expn = 0;  
        head->next = NULL;  
        pc = head;  
        L2 = Reverse(L2);  
        pa = L1->next ;  
        pb = L2->next ;  
        while(pa != NULL && pb != NULL)  
        {  
            if(pa->expn == pb->expn)  
            {  
                u = (PLinkList)malloc(sizeof(PolyNode));  
                if(!u)  
                {  
                    return NULL;  
                }  
                u->coef = pa->coef + pb->coef ;  
                u->expn = pa->expn ;  
                pa = pa->next ;  
                pb = pb->next ;  
                u->next = pc->next ;  
                pc->next = u;  
                pc = u;  
            }  
            else if(pa->expn > pb->expn)  
            {  
                u = (PLinkList)malloc(sizeof(PolyNode));  
                if(!u)  
                {  
                    return NULL;  
                }  
                u->coef = pa->coef ;  
                u->expn = pa->expn ;  
                pa = pa->next ;  
                u->next = pc->next ;  
                pc->next = u;  
                pc = u;  
            }  
            else  
            {  
                u = (PLinkList)malloc(sizeof(PolyNode));  
                if(!u)  
                {  
                    return NULL;  
                }  
                u->coef = pb->coef ;  
                u->expn = pb->expn ;  
                pb = pb->next ;  
                u->next = pc->next ;  
                pc->next = u;  
                pc = u;  
            }  
        }  
        L2 = Reverse(L2);  
        return head;  
    }  
      
    PolyNode *Subtraction(PLinkList L1,PLinkList L2)//多项式的减法  
    {  
        PolyNode *pa,*pb,*pc,*u,*head;  
        head = (PLinkList)malloc(sizeof(PolyNode));  
        if(!head)  
        {  
            return NULL;  
        }  
        head->coef = 0.0;  
        head->expn = 0;  
        head->next = NULL;  
        pc = head;  
        pa = L1->next ;  
        pb = L2->next ;  
        while(pa != NULL && pb != NULL)  
        {  
            if(pa->expn == pb->expn)  
            {  
                u = (PLinkList)malloc(sizeof(PolyNode));  
                if(!u)  
                {  
                    return NULL;  
                }  
                u->coef = pa->coef - pb->coef ;  
                u->expn = pa->expn ;  
                pa = pa->next ;  
                pb = pb->next ;  
                u->next = pc->next ;  
                pc->next = u;  
                pc = u;  
            }  
            else if(pa->expn > pb->expn)  
            {  
                u = (PLinkList)malloc(sizeof(PolyNode));  
                if(!u)  
                {  
                    return NULL;  
                }  
                u->coef = pa->coef ;  
                u->expn = pa->expn ;  
                pa = pa->next ;  
                u->next = pc->next ;  
                pc->next = u;  
                pc = u;  
            }  
            else  
            {  
                u = (PLinkList)malloc(sizeof(PolyNode));  
                if(!u)  
                {  
                    return NULL;  
                }  
                u->coef = pb->coef ;  
                u->expn = pb->expn ;  
                pb = pb->next ;  
                u->next = pc->next ;  
                pc->next = u;  
                pc = u;  
            }  
        }  
        return head;  
    }  
      
    PolyNode *Reverse(PLinkList head)//将生成的链表逆置,使一元多项式呈指数递增形式  
    {  
        PolyNode *q,*r,*p = NULL;  
        q = head->next ;  
        while(q)  
        {  
            r = q->next ;  
            q->next = p;  
            p = q;  
            q = r;  
        }  
        head->next = p;  
        return head;  
    }  
      
    PolyNode *MultiplyPolyn(PLinkList L1,PLinkList L2)//多项式的乘法  
    {  
        PolyNode *pa,*pb,*pc,*u,*head;  
        int k,maxExp;  
        float coef;  
        head = (PLinkList)malloc(sizeof(PolyNode));  
        if(!head)  
        {  
            return NULL;  
        }  
        head->coef = 0.0;  
        head->expn = 0;  
        head->next = NULL;  
        if(L1->next != NULL && L2->next != NULL)  
        {  
            maxExp = L1->next->expn +L2->next->expn ;  
        }  
        else  
        {  
            return head;  
        }  
        pc = head;  
        L2 = Reverse(L2);  
        for(k = maxExp;k >= 0;k--)  
        {  
            pa = L1->next ;  
            while(pa != NULL && pa->expn > k)  
            {  
                pa = pa->next ;  
            }  
            pb = L2->next ;  
            while(pb != NULL && pa != NULL && pa->expn+pb->expn < k)  
            {  
                pb= pb->next ;  
            }  
            coef = 0.0;  
            while(pa != NULL && pb != NULL)  
            {  
                if(pa->expn +pb->expn == k)  
                {  
                    coef += pa->coef *pb->coef ;  
                    pa = pa->next ;  
                    pb = pb->next ;  
                }  
                else if(pa->expn +pb->expn > k)  
                {  
                    pa = pa->next ;  
                }  
                else  
                {  
                    pb = pb->next ;  
                }  
            }  
            if(coef != 0.0)  
            {  
                u = (PLinkList)malloc(sizeof(PolyNode));  
                u->coef = coef;  
                u->expn = k;  
                u->next = pc->next ;  
                pc->next = u;  
                pc = u;  
            }  
        }  
        L2 = Reverse(L2);  
        return head;  
    }  
    
    
    //测试 
    int main(void)  
    {  
        PLinkList A,B,C,D,E;  
        A = CreatePolyn();  
        printf("A(x) =");  
        OutPut(A);  
        printf("
    ");  
        B = CreatePolyn();  
        printf("B(x) =");  
        OutPut(B);  
        printf("
    ");  
        C = MultiplyPolyn(A,B);  
        printf("C(x) = A(x)*B(x) =");  
        OutPut(C);  
        printf("
    ");  
        D = Addition(A,B);  
        printf("D(x) = A(x)+B(x) =");  
        OutPut(D);  
        printf("
    ");  
        E = Subtraction(A,B);  
        printf("E(x) = A(x)-B(x) =");  
        OutPut(E);  
        printf("
    ");  
        return 0;  
    }
  • 相关阅读:
    MySQL——UPDATE更新
    MySQL——WHERE字句
    MySQL——查询数据
    MySQL——删除数据表
    MySQL——插入数据
    MySQL——创建数据表
    MySQL——数据类型
    MySQL——选择数据库
    MySQL——删除数据库
    MySQL——创建数据库
  • 原文地址:https://www.cnblogs.com/zw1sh/p/12447183.html
Copyright © 2011-2022 走看看