zoukankan      html  css  js  c++  java
  • 数据结构单链表

    本文内容

    • 初始化单链表-带头节点
    • 自动创建单链表-逆序
    • 自动创建单链表-顺序
    • 手动创建单链表-输入
    • 自动创建单链表-数组
    • 创建交叉的单链表
    • 创建带环的单链表
    • 将一般的单链表转换成循环单链表
    • 将循环单链表转换成一般的单链表
    • 销毁单链表
    • 单链表长度
    • 带环的单链表长度
    • 在单链表第i个位置插入元素e
    • 删除单链表第i个元素
    • 合并单链表
    • 单链表置逆
    • 单链表排序
    • 单链表是否包含环
    • 单链表是否为循环单链表
    • 获得单链表第i个节点元素
    • 获得元素为e的节点位置
    • 获得单链表的中间节点元素
    • 查找单链表元素为e的指针
    • 查找单链表倒数第K个节点的元素
    • 查找交叉的单链表的交叉节点
    • 查找带环的单链表的环入口节点
    • 输出单链表,不输出头节点
    • 输出单链表,输出头节点
    • 输出带环的单链表

    linklist.h 声明文件

    typedef int ElementType;
     
    #ifndef LIST_H_INCLUDED
    #define LIST_H_INCLUDED
     
    struct LNode;
    typedef struct LNode *linkList;
    typedef linkList LinkList;
    typedef linkList LinkPos;
     
    /* 初始化-创建头节点 */
    LinkList InitList_L();
    /* 自动创建-逆序 */
    LinkList CreateAutoList_L01( int length );
    /* 自动创建-顺序 */
    LinkList CreateAutoList_L02( int length );
    /* 手动创建-输入 */
    LinkList CreateHandList_L( int length );
    /* 自动创建-数组 */
    LinkList CreateHandArrList_L( int a[], int length );
    /* 创建交叉单链表 */
    void CreateIntersectantList_L( LinkList La, LinkList Lb, int index);
    /* 创建带环的单链表 */
    LinkList CreateLoopList_L( LinkList La, LinkList Lb, int index);
    /* 将一般的单链表转换成循环单链表 */
    void ConvertCircularList_L( LinkList L );
    /* 将循环单链表转换成一般的单链表 */
    void ConvertGeneralList_L( LinkList L );
    /* 销毁单链表 */
    void DestroyList_L( LinkList L );
     
    /* 单链表长度 */
    int LengthList_L( LinkList L );
    /* 带环的单链表长度 */
    int LengthLoopList_L( LinkList L );
    /* 在单链表第i个位置插入元素e */
    void InsertList_L( LinkList L, int index, ElementType e );
    /* 删除单链表第i个元素 */
    void DeleteList_L( LinkList L, int index, ElementType *e );
    /* 合并单链表 */
    void MergeList_L( LinkList La, LinkList Lb );
    /* 单链表置逆 */
    void ReverseList_L01( LinkList L );
    void ReverseList_L02( LinkPos pHead, LinkPos pTail);
    /* 单链表排序 */
    void SortList_L( LinkList L );
    /* 单链表是否包含环 */
    int IsLoopList_L( LinkList L );
    /* 单链表是否为循环单链表 */
    int IsCircularList_L( LinkList L );
     
    /* 获得单链表第i个节点元素 */
    ElementType GetList_L( LinkList L, int i );
    /* 获得元素为e的节点位置 */
    int LocateList_L( LinkList L, ElementType e );
     
    /* 获得单链表中间节点元素 */
    ElementType FindMiddleList_L( LinkList L );
    /* 查找单链表元素为e的指针 */
    LinkPos FindList_L( LinkList L, ElementType e );
    /* 查找单链表倒数第K个节点的元素 */
    ElementType FindKthList_L( LinkList L, int KthIndex );
    /* 查找交叉链表交叉节点 */
    ElementType FindIntersectantList_L( LinkList La, LinkList Lb, int testIndex );
    /* 查找环入口节点 */
    ElementType FindLoopList_L( LinkList L );
     
    /* 输出单链表,不输出头节点 */
    void PrintList_L( LinkList L);
    /* 输出单链表,输出头节点 */
    void PrintAllList_L( LinkList L );
    /* 输出带环的单链表 */
    void PrintLoopList_L( LinkList L );
     
    #endif


    linklist.c 实现文件

    #include "linklist.h"
    #include <stdio.h>
    #include <stdlib.h>
     
    struct LNode
    {
        ElementType Element;
        linkList    Next;
    };
    /* 初始化 */
    LinkList InitList_L()
    {
        LinkList L = (linkList)malloc( sizeof( struct LNode ) );
        L->Element = -1;
        L->Next = NULL;
        return L;
    }
    /* 自动创建-逆序 */
    LinkList CreateAutoList_L01( int length )
    {
        int i;
        LinkPos n;
     
        LinkList L = InitList_L();
        for(i=1 ; i<=length ; i++)
        {
            n = (linkList)malloc( sizeof( struct LNode ) );
            n->Element = i + 1000;
            n->Next = L->Next;
            L->Next = n;
        }
        return L;
    }
    /* 自动创建-顺序 */
    LinkList CreateAutoList_L02( int length )
    {
        int i;
        LinkPos n, p;
     
        LinkList L = InitList_L();
        p = L;
        for(i=1 ; i<=length ; i++)
        {
            n = (linkList)malloc( sizeof( struct LNode ) );
            n->Element = i + 2000;
            p->Next = n;
            p = n;
        }
        p->Next = NULL;
        return L;
    }
    /* 手动创建-输入 */
    LinkList CreateHandList_L( int length )
    {
        int i;
        LinkPos n;
     
        LinkList L = InitList_L();
        for(i=length ; i>0 ; --i)
        {
            n = (linkList)malloc( sizeof( struct LNode ) );
            scanf("%d",& n->Element);
            n->Next = L->Next;
            L->Next = n;
        }
        return L;
    }
    /* 自动创建-数组 */
    LinkList CreateHandArrList_L( int a[], int length )
    {
        int i;
        LinkList L;
        LinkPos p;
     
        L = InitList_L();
        for(i=length-1 ; i>=0 ; --i)
        {
            p = (linkList)malloc( sizeof( struct LNode ) );
            p->Element = a[i];
            p->Next = L->Next;
            L->Next = p;
        }
        return L;
    }
    /* 创建交叉链表 */
    /* index: {1, LengthList_L} */
    void CreateIntersectantList_L( LinkList La, LinkList Lb, int index)
    {
        LinkPos pa, pb;
        int count = 0;
     
        pa = La;
        pb = Lb;
        while( pa->Next && count<index )
        {
            pa = pa->Next;
            count++;
        }
        while( pb->Next ) pb = pb->Next;
        pb->Next = pa;
    }
    /* 创建带环的单链表 */
    /* index: {1, LengthList_L} */
    LinkList CreateLoopList_L( LinkList La, LinkList Lb, int index)
    {
        LinkPos pa, pb;
        int count = 0;
        pa = La;
        pb = Lb;
        // 交叉单链表
        while( pa->Next && count<index )
        {
            pa = pa->Next;
            count++;
        }
        while( pb->Next ) pb = pb->Next;
        pb->Next = pa;
        // 环单链表
        while( pa->Next) pa = pa->Next;
        pa->Next = Lb->Next;
        return La;
    }
    /* 一般单链表转换成循环单链表 */
    void ConvertCircularList_L( LinkList L )
    {
        LinkPos p;
        p = L;
        while( p->Next ) p = p->Next;
        p->Next = L;
    }
    /* 循环单链表转换成一般单链表 */
    void ConvertGeneralList_L( LinkList L )
    {
        LinkPos p;
     
        p = L;
        while( p->Next != L ) p = p->Next;
        if( p->Next == L ) p->Next = NULL;
    }
    /* 销毁单链表 */
    void DestroyList_L( linkList L )
    {
        LinkPos P, q;
     
        P = L->Next;
        L->Next = NULL;
        while( P != NULL )
        {
            q = P->Next;
            free( P );
            P = q;
        }
        free(L);
    }
    /* 单链表长度 */
    int LengthList_L( LinkList L )
    {
        int len = 0;
        LinkPos p;
     
        p = L->Next;
        while( p )
        {
            len++;
            p = p->Next;
        }
        return len;
    }
    /* 包含环的单链表的长度 */
    int LengthLoopList_L( LinkList L )
    {
        LinkPos f, s;
        int count=0;
     
        f = L;
        s = L;
        while( f && f->Next )
        {
            s = s->Next;
            f = f->Next->Next;
            count++;
            if( s==f ) break;
        }
        if( !f || !f->Next ) return count;
        s = L;
        while( s != f )
        {
            s = s->Next;
            f = f->Next;
            count++;
        }
        return count;
    }
    /* 插入 */
    /* index:{ 0, Length(L)+1 } */
    void InsertList_L( LinkList L, int index, ElementType e )
    {
        int j = 0;
        LinkPos p, n;
     
        p = L;
        // p->Next && j < index-1 这个条件当index为 Length(L)+1 时,不能插入链表尾
        while( p && j < index-1 ) {
            p = p->Next;
            j++;
        }
        if( p && j <= index ) // p->Next && j <= index
        {
            n = (linkList)malloc( sizeof(struct LNode) );
            n->Element = e;
            n->Next = p->Next;
            p->Next = n;
        }
    }
    /* 删除 */
    /* index: { 1, Length(L) }*/
    void DeleteList_L( LinkList L, int index, ElementType *e )
    {
        int j = 0;
        LinkPos p, q;
     
        p = L;
        while( p->Next && j < index-1 )
        {
            p = p->Next;
            j++;
        }
        if( p->Next && j <=index )
        {
            *e = p->Next->Element;
            q = p->Next;
            p->Next = q->Next;
            free( q );
        }
    }
    /* 合并 */
    void MergeList_L( LinkList La, LinkList Lb )
    {
        LinkPos pa, pb, pc;
        pa = La->Next;
        pb = Lb->Next;
        pc = La;
        while( pa && pb )
        {
            if( pa->Element <= pb->Element)
            {
                pc->Next = pa;
                pc = pa;
                pa = pa->Next;
            }
            else
            {
                pc->Next = pb;
                pc = pb;
                pb = pb->Next;
            }
        }
        pc->Next = pa ? pa : pb;
        free( Lb );
    }
    /* 置逆 */
    void ReverseList_L01( LinkList L )
    {
        LinkPos p, q, r;
     
        p = L;
        q = p->Next;
        while( q )
        {
            r = q->Next;
            q->Next = p;
            p = q;
            q = r;
        }
        L->Next->Next = NULL;
        L->Next = p;
    }
    void ReverseList_L02( LinkPos pHead, LinkPos pTail)
    {
        LinkPos p;
     
        if (pHead == NULL || pHead->Next == NULL) return;
        // Address pTail->Next as a temp pointer
        // Since it should NULL all the times
        pTail->Next = pHead;
        p = pHead->Next;
        // Don't need worry about the cleanup things on the next pointer of pFirst
        while( p != pTail )
        {
            // Address pHead->Next as a temp pointer
            // Since it will be useless after the first iteration
            pHead->Next = p->Next;
            // pTail->Next has pointed to pHead
            p->Next = pTail->Next;
            pTail->Next = p;
            p = pHead->Next;
        }
        pHead->Next = NULL;
    }
    /* 排序 */
    void SortList_L( LinkList L )
    {
        LinkPos p, q, r, s;
     
        LinkList Lt = InitList_L();
        p = Lt;
        p->Next = L;
        while( p->Next )
        {
            q = p->Next;
            r = p;
            while( q->Next )
            {
                if( q->Next->Element < r->Next->Element ) r = q;
                q = q->Next;
            }
            if( r != p )
            {
                s = r->Next;
                r->Next = p->Next;
                r = s->Next;
                s->Next = p->Next->Next;
                p->Next->Next = r;
                p->Next = s;
            }
            p = p->Next;
        }
        L = Lt->Next;
        free( Lt );
    }
    /* 是否存在环 */
    int IsLoopList_L( LinkList L )
    {
        LinkPos f, s;
     
        f = L->Next;
        s = L;
        while( f && f != s )
        {
            f = f->Next->Next;
            s = s->Next;
        }
        if( !f ) return 0;
        else return 1;
    }
    /* 是否为循环单链表 */
    int IsCircularList_L( LinkList L )
    {
        LinkPos p;
     
        p = L;
        while( p->Next && p->Next!=L ) p = p->Next;
        if( !p->Next ) return 0;
        else return 1;
    }
    /* 查找第i个节点 */
    /* index: { 1, LengthList_L() }*/
    ElementType GetList_L( LinkList L, int index )
    {
        int count = 0;
        LinkPos p;
     
        p = L;
        while( p && count<index )
        {
            p = p->Next;
            count++;
        }
        if( !p )
            return -1;
        else
            return p->Element;
    }
    /* 查找X节点的索引 */
    int LocateList_L( LinkList L, ElementType e )
    {
        int index = 1;
        LinkPos p;
     
        p = L->Next;
        while( p && p->Element==e )
        {
            p = p->Next;
            index++;
        }
        if(p == NULL) return 0;
        else return index;
    }
    /* 查找中间节点 */
    /* 思想:一个指针每次走一步,另一个指针每次走两步 */
    /* 若LengthList_L为奇数,则返回中间节点,否则返回中间两个节点的前一个 */
    ElementType FindMiddleList_L( LinkList L )
    {
        LinkPos p, q;
        p = L;
        q = L;
        while( p )
        {
            p = p->Next;
            if( !p->Next )
            {
                q = q->Next;
                break;
            }
     
            p = p->Next;
            if( !p->Next )
            {
                break;
            }
            q = q->Next;
        }
        return q->Element;
    }
    /* 查找X节点 */
    LinkPos FindList_L( LinkList L, ElementType e )  
    {  
        LinkPos P;  
      
        P = L->Next;  
        while( P && P->Element!=e ) P = P->Next;  
        return P;  
    } 
    /* 查找倒数第K个节点 */
    /* KthIndex: { 1, LengthList_L() }*/
    ElementType FindKthList_L(LinkList L, int KthIndex)
    {
        LinkPos p, q;
        int i = 0;
        p = L;
        q = L;
        while( p && i!=KthIndex )
        {
            p = p->Next;
            i++;
        }
        while( p )
        {
            p = p->Next;
            q = q->Next;
        }
        return q->Element;
    }
    /* 查找交叉链表交叉节点 */
    ElementType FindIntersectantList_L( LinkList La, LinkList Lb, int testIndex )
    {
        LinkList pa, pb;
        ElementType e;
     
        pa = La;
        pb = Lb;
        CreateLoopList_L(pa, pb, testIndex);
        e = FindLoopList_L(pa);
     
        pb = Lb->Next;
        while( pb->Next != Lb->Next ) pb = pb->Next;
        pb->Next = NULL;
        return e;
    }
    /* 查找环入口节点 */
    ElementType FindLoopList_L( LinkList L )
    {
        LinkPos s, f;
     
        s = L;
        f = L;
        while( f && f->Next )
        {
            s = s->Next;
            f = f->Next->Next;
            if( s == f ) break;
        }
        if( !f || !f->Next ) return -1;
        s = L;
        while( s!=f )
        {
            s = s->Next;
            f = f->Next;
        }
        return s->Element;
    }
    /* 输出单链表,不输出头节点 */
    void PrintList_L( LinkList L )
    {
        LinkPos p;
        int index = 0;
     
        p = L->Next;
        printf("LENGTH %d, PRINT linkList.../n", LengthList_L(L));
        while( p )
        {
            printf("INDEX = %3d, VALUE = %4d/n", ++index, p->Element);
            p = p->Next;
        }
        printf("END./n/n");
    }
    /* 输出单链表,输出头节点 */
    void PrintAllList_L( LinkList L )
    {
        LinkPos p;
        int index;
     
        index = 0;
        p = L;
        printf("LENGTH %d, PRINT linkList.../n", LengthList_L(L));
        while( p )
        {
            printf("INDEX = %3d, VALUE = %4d/n", index++, p->Element);
            p = p->Next;
        }
        printf("END./n/n");
    }
    /* 输出带环的单链表 */
    void PrintLoopList_L( LinkList L )
    {
        LinkPos f, s;
     
        f = L;
        s = L;
        while( f && f->Next )
        {
            printf("slow VALUE = %4d, fast VALUE = %4d/n", s->Element, f->Element);
            s = s->Next;
            f = f->Next->Next;
            if( s == f ) break;
        }
        if( !f || !f->Next ) return;
        s = L;
        while( s != f )
        {
            printf("slow VALUE = %4d, fast VALUE = %4d/n", s->Element, f->Element);
            s = s->Next;
            f = f->Next;
        }
        printf("s point value=%d, f point value=%d/n", s->Element, f->Element);
        printf("END./n/n");
    }

    自己写个入口函数main函数调用一下,比如,创建 CreateAutoList_L01 一个单链表 CreateAutoList_L01,再销毁 DestoryList_L 它;创建 CreateIntersectantList_L 一个交叉单链表,然后查找 FindIntersectantList_L 交叉节点;创建 CreateLoopList_L 一个带环的单链表,然后判断单链表是否包含环 IsLoopList_L,并查找环的入口节点 FindLoopList_L 等等。

    下载 Demo

  • 相关阅读:
    【Docker】命令 restart
    【Docker】命令 rename
    小知识点笔记一(原始版)
    Java常用类——匿名对象
    Java常用类——Arrays工具类
    Java常用类——Scanner类
    Python怎么测试异步接口
    接口测试面试题
    Pycharm使用常见问题
    接口测试命令Httpie的使用
  • 原文地址:https://www.cnblogs.com/liuning8023/p/2160073.html
Copyright © 2011-2022 走看看