zoukankan      html  css  js  c++  java
  • 数据结构之链表操作

          面试中单链表的相关操作也是常考的内容,本博文也是之前学习时的笔记,在此记录下来,以便日后用到,同时欢迎批评指正。

          一、基本操作 

          单链表的基本操作包括链表的创建、销毁、判空、索引、插入、删除等,下面是在链表的相关操作程序,链表的定义如下:

          typedef struct LNode{  

    int data;

    struct LNode *next;

    }LNode,*LinkList;

    此链表是带有头结点的,因此空链表的形式是 head->next=NULL .

           1. 链表的初始化

    LinkList InitList(void)    

    {
        LinkList head = NULL;
        head = (LinkList)malloc(sizeof(LNode));
        
        head->data = 0;
        head->next = NULL;    
        return head;    

    } 

            2.链表的销毁

     void DestoryList(LinkList L)        

    {
        LinkList pTemp = L->next,
            qTemp=L->next;
        if (L->next==NULL)                //此为空链表不需要再删除
            {
                printf("the list has already be empty!\n");
            }
         else{
               while(pTemp)
                {
                    qTemp = pTemp->next;
                    free(pTemp);
                    pTemp = qTemp;
                }
                L->next = pTemp;
            }
        }

            3.链表的判空

     bool ListEmpty(LinkList L)

    {
        if(L->next == NULL)
            {
                return TRUE;
            }
            else return FALSE;
    }    

            4.链表的长度

    int ListLength(LinkList L)                

        LinkList pTemp = L->next;
        int NodeCount = 0;
        for(;pTemp;pTemp = pTemp->next)
        {
            NodeCount++;
        }
        return NodeCount;

    } 

             5.链表的索引

    int GetElem(LinkList L,int i,int* e)        
    {                                //取出第i个节点
        LinkList pTemp = L;
        int j = 0;
        while(pTemp && j<i)
        {
            pTemp = pTemp->next;
            j++;
        }
        if(!pTemp || j>i)
            {
                printf("GetElem Error!\n");
                exit(0);
            }
        *e = pTemp->data;
    return *e;    

    } 

             6.链表的插入

    void Insert(LinkList L,int i,int e)
    {                                //在第i个节点插入e,因此需要找到第i-1节点,然后在其后插入
        LinkList Ins,
                pTemp = L;
        int j = 0;
        while(pTemp && j<i-1)
        {
            pTemp = pTemp->next;
            j++;
        }
        if(!pTemp || j>i-1)
            {
             printf("Error!\n");
             exit(0);
        }
        Ins = (LinkList)malloc(sizeof(LNode));
        if(Ins==NULL) printf("allocate memory error!\n");
        Ins->data = e;
        Ins->next = pTemp->next;
        pTemp->next = Ins;            

    } 

            7.链表的删除

    void Delete(LinkList L,int i,int e)
    {                                //删除第i个节点,因此找到第i-1节点,然后删除其后的节点
        LinkList Del,
                pTemp = L;
        int j = 0;
        while(pTemp->next && j<i-1)
        {
            pTemp = pTemp->next;
            j++;
        }
        if(!(pTemp->next) || j>i-1
            {
                    printf("error!\n");
                    exit(0);
            }    
        Del = pTemp->next;
        pTemp->next = Del->next;
        e = Del->data;
        free(Del);

    }

            8. 链表的创建

    该操作有两种方法,一种是头插法,另一种是尾插法

    void CreateList(LinkList &L,int n)

    {    //头插法,每次都是在链表的头部插入元素
        L = (LinkList)malloc(sizeof(LNode));
        if(L == NULL)
            {
                printf("error!");
                exit(0);
            }
        L->next=NULL;
        for( i=0;i<n;i++)
        {
            p = (LinkList)malloc(sizeof(LNode));
            scanf(&p->data);
            p->next=L->next;
            L->next = p;
        }

    } 

    void CreateList(LinkList &L,int n)
    {  //尾插法,每次都是从链表的尾部插入元素,最后把链表的next指针赋值为NULL
        L = (LinkList)malloc(sizeof(LNode));
        if (L == NULL) 
        {
            printf("error!");
            exit(0);
        }
        L->next = NULL;
        pre = L;
        for(i=0;i<n;i++)
        {
            p = (LinkList)malloc(sizeof(LNode));
            scanf(&p->data);
            pre ->next = p;
            pre = p;
        }
        pre->next = NULL;

    } 

             二、其他操作

            1.链表的反转

    ListList ReverseList(LinkList L )

    {  //带有头结点,p为L的第一个元素
        LinkList p = L->next;
        LinkList prev = NULL,temp = NULL;
        while(p!=NULL)
        {
            temp = p;
            p = p->next;
            temp->next = prev;
            prev = temp;
        }
        L->next = prev;
        return L;

    } 

    链表的反转也可以使用递归来做! 

    2.删除一个元素x

    ListList ReverseList(LinkList L )
    {  //带有头结点,p为L的第一个元素
        LinkList p = L->next;
        LinkList prev = NULL,temp = NULL;
        while(p!=NULL)
        {
            temp = p;
            p = p->next;
            temp->next = prev;
            prev = temp;
        }
        L->next = prev;
        return L;

    } 

    3.删除所有重复的元素

     void DeleteAllX(LinkList L)

    {
        LinkList p = L,
                 pPrev,
                 pCurr;
        while( p!= NULL)
        {
            pPrev = p;
            pCurr = p->next;
            while(pCurr != NULL)
            {
                if(pCurr->data == p->data)
                    {
                        pPrev->next = pCurr->next;
                        free(pCurr);
                        pCurr = pPrev->next;
                    }
                else
                    {
                        pPrev = pCurr;
                        pCurr = pCurr->next;
                    }
            }
            p = p->next;
        }
    }

      4.判断链表是不是有环

    Bool IsLoop(LinkList head)
    {
        LinkList slow = head,
                         fast = head;
        while(fast && fast->next)
        {
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast)
                break;
        }
        return !(fast == NULL || fast->next == NULL);

    } 

      如果链表带环的话,找出环的入口,这个原理网上有介绍,算法也一大堆!

      5.将链表分为两个链表,一个为奇数序的元素,另一个为偶数序的元素

    void splice(LinkList La, LinkList Lb)
    {
        LinkList Lb,pb,pa,pTemp;
        Lb = (LinkList)malloc(sizeof(LNode));
        pa = La->next;
        pb = Lb;
        while(pa->next)
        {
            pTemp = pa->next;
            pa->next = pTemp->next;
            pb->next = pTemp;
            pb = pTemp;
            pa = pa->next;
        }
        pb->next = NULL;

    } 

      6.单链表的插入排序

    void InsertSort(LinkList L)
    {
        LinkList p,q,pre,r;
        
        p = L->next;
        while(p->next)
        {
            q = p->next;
            if(q->data < p->data)
                {
                    pre = L;
                    r = L->next;
                    while(r!=p && r->data < q->data)
                    {
                        pre = r;
                        r = r->next;
                    }
                  p->next = q->next;
                  q->next = r;
                  pre->next = q;
                }
            else
                p = p->next;
        }

    } 

      7.单链表的选择排序

     void SelectSort(LinkList L)

    //r总是指向最小的节点
        LinkList p,q,r;
        p = L->next;
        while(p->next)
        {
            r = p;
            q = p->next;
            while(q)
            {
                if(r->data > q->data)
                     r = q;
                q = q->next;
            }
            if(r != p)
                {
                    temp = p->data;
                    p->data = r->data;
                    r->data = temp;
                }
            p = p->next;
        }
    }
  • 相关阅读:
    【转】【金蝶K3Cloud】 分页账表
    【转】【金蝶K3Cloud】 树形账表
    【金蝶K3Cloud】Python拼接字段
    性能分析及调优
    性能测试指南
    性能测试--测试指标
    性能测试--术语解释
    BurpSuite 安装使用
    BeEF 安装使用
    win10与vmware 中的kali linux 共享文件夹
  • 原文地址:https://www.cnblogs.com/kingcucumber/p/2872552.html
Copyright © 2011-2022 走看看