• 链表


    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)

    3、双向链表

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

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

  • 相关阅读:
    面向对象3
    面向对象1
    面向对象2
    javascript的dom操作部分
    网页javascript部分
    网页css样式表部分
    网页HTML部分
    特殊集合和结构体
    集合
    数组 -自动遍历数组-冒泡排序
  • 原文地址:https://www.cnblogs.com/zw1sh/p/12422804.html
Copyright © 2020-2023  润新知