zoukankan      html  css  js  c++  java
  • 数据-第10课-循环链表

    第10课-循环链表

    l  单链表的局限

    (1)      单链表可以用于表示任意的线性关系。

    (2)      有些线性关系是循环的,即没有队尾元素 ,即没有队尾元素。

    1. 循环链表的定义

    将单链表中最后一个数据元素的next指针指向第一个元素。

    2. 循环链表拥有单链表的所有操作

    (1)      创建链表。

    (2)      销毁链表。

    (3)      获取链表长度。

    (4)      清空链表。

    (5)      获取第pos个元素操作。

    (6)      插入元素到位置pos。

    (7)      删除位置pos。

    例子--将单链表改写成循环链表

    CircleList.h

    #ifndef _CIRCLELIST_H_

    #define _CIRCLELIST_H_

    typedef void CircleList;

    typedef struct _tag_CircleListNode CircleListNode;

    struct _tag_CircleListNode

    {

        CircleListNode* next;

    };

    CircleList* CircleList_Create();

    void CircleList_Destroy(CircleList* list);

    void CircleList_Clear(CircleList* list);

    int CircleList_Length(CircleList* list);

    int CircleList_Insert(CircleList* list, CircleListNode* node, int pos);

    CircleListNode* CircleList_Get(CircleList* list, int pos);

    CircleListNode* CircleList_Delete(CircleList* list, int pos);

    CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);

    CircleListNode* CircleList_Reset(CircleList* list);

    CircleListNode* CircleList_Current(CircleList* list);

    CircleListNode* CircleList_Next(CircleList* list);

    #endif

    CircleList.h

    #include <stdio.h>

    #include <malloc.h>

    #include "CircleList.h"

    typedef struct _tag_CircleList

    {

        CircleListNode header;

        CircleListNode* slider;

        int length;

    } TCircleList;

    CircleList* CircleList_Create() // O(1)

    {

        TCircleList* ret = (TCircleList*)malloc(sizeof(TCircleList));

       

        if( ret != NULL )

        {

            ret->length = 0;

            ret->header.next = NULL;

            ret->slider = NULL;

        }

       

        return ret;

    }

    void CircleList_Destroy(CircleList* list) // O(1)

    {

        free(list);

    }

    void CircleList_Clear(CircleList* list) // O(1)

    {

        TCircleList* sList = (TCircleList*)list;

       

        if( sList != NULL )

        {

            sList->length = 0;

            sList->header.next = NULL;

            sList->slider = NULL;

        }

    }

    int CircleList_Length(CircleList* list) // O(1)

    {

        TCircleList* sList = (TCircleList*)list;

        int ret = -1;

       

        if( sList != NULL )

        {

            ret = sList->length;

        }

       

        return ret;

    }

    int CircleList_Insert(CircleList* list, CircleListNode* node, int pos) // O(n)

    {

        TCircleList* sList = (TCircleList*)list;

        int ret = (sList != NULL) && (pos >= 0) && (node != NULL);

        int i = 0;

       

        if( ret )

        {

            CircleListNode* current = (CircleListNode*)sList;

           

            for(i=0; (i<pos) && (current->next != NULL); i++)

            {

                current = current->next;

            }

           

            node->next = current->next;

            current->next = node;

           

            if( sList->length == 0 )

            {

                sList->slider = node;

                node->next = node;

            }

           

            sList->length++;

        }

       

        return ret;

    }

    CircleListNode* CircleList_Get(CircleList* list, int pos) // O(n)

    {

        TCircleList* sList = (TCircleList*)list;

        CircleListNode* ret = NULL;

        int i = 0;

       

        if( (sList != NULL) && (pos >= 0) )

        {

            CircleListNode* current = (CircleListNode*)sList;

           

            for(i=0; i<pos; i++)

            {

                current = current->next;

            }

           

            ret = current->next;

        }

       

        return ret;

    }

    CircleListNode* CircleList_Delete(CircleList* list, int pos) // O(n)

    {

        TCircleList* sList = (TCircleList*)list;

        CircleListNode* ret = NULL;

        int i = 0;

       

        if( (sList != NULL) && (pos >= 0) )

        {

            CircleListNode* current = (CircleListNode*)sList;

            CircleListNode* first = sList->header.next;

            CircleListNode* last = (CircleListNode*)CircleList_Get(sList, sList->length - 1);

           

            for(i=0; i<pos; i++)

            {

                current = current->next;

            }

           

            ret = current->next;

            current->next = ret->next;

           

            sList->length--;

           

            if( first == ret )

            {

                sList->header.next = ret->next;

                last->next = ret->next;

            }

           

            if( sList->slider == ret )

            {

                sList->slider = ret->next;

            }

           

            if( sList->length == 0 )

            {

                sList->header.next = NULL;

                sList->slider = NULL;

            }

        }

       

        return ret;

    }

    CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node) // O(n)

    {

        TCircleList* sList = (TCircleList*)list;

        CircleListNode* ret = NULL;

        int i = 0;

       

        if( sList != NULL )

        {

            CircleListNode* current = (CircleListNode*)sList;

           

            for(i=0; i<sList->length; i++)

            {

                if( current->next == node )

                {

                    ret = current->next;

                    break;

                }

               

                current = current->next;

            }

            

            if( ret != NULL )

            {

                CircleList_Delete(sList, i);

            }

        }

       

        return ret;

    }

    CircleListNode* CircleList_Reset(CircleList* list) // O(1)

    {

        TCircleList* sList = (TCircleList*)list;

        CircleListNode* ret = NULL;

       

        if( sList != NULL )

        {

            sList->slider = sList->header.next;

            ret = sList->slider;

        }

       

        return ret;

    }

    CircleListNode* CircleList_Current(CircleList* list) // O(1)

    {

        TCircleList* sList = (TCircleList*)list;

        CircleListNode* ret = NULL;

       

        if( sList != NULL )

        {

            ret = sList->slider;

        }

       

        return ret;

    }

    CircleListNode* CircleList_Next(CircleList* list) // O(1)

    {

        TCircleList* sList = (TCircleList*)list;

        CircleListNode* ret = NULL;

       

        if( (sList != NULL) && (sList->slider != NULL) )

        {

            ret = sList->slider;

            sList->slider = ret->next;

        }

       

        return ret;

    }

    main.c

    #include <stdio.h>

    #include <stdlib.h>

    #include "CircleList.h"

    /* run this program using the console pauser or add your own getch, system("pause") or input loop */

    struct Value

    {

        CircleListNode header;

        int v;

    };

    int main(int argc, char *argv[])

    {

        int i = 0;

        CircleList* list = CircleList_Create();

       

        struct Value v1;

        struct Value v2;

        struct Value v3;

        struct Value v4;

        struct Value v5;

        struct Value v6;

        struct Value v7;

        struct Value v8;

       

        v1.v = 1;

        v2.v = 2;

        v3.v = 3;

        v4.v = 4;

        v5.v = 5;

        v6.v = 6;

        v7.v = 7;

        v8.v = 8;

       

        CircleList_Insert(list, (CircleListNode*)&v1, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v2, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v3, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v4, CircleList_Length(list));

       

        CircleList_Insert(list, (CircleListNode*)&v5, 5);

        CircleList_Delete(list, 0);

       

        for(i=0; i<2*CircleList_Length(list); i++)

        {

            struct Value* pv = (struct Value*)CircleList_Get(list, i);

           

            printf("%d ", pv->v);

        }

       

        printf(" ");

       

        while( CircleList_Length(list) > 0 )

        {

            struct Value* pv = (struct Value*)CircleList_Delete(list, 0);

           

            printf("%d ", pv->v);

        }

       

        printf(" ");

       

        CircleList_Insert(list, (CircleListNode*)&v1, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v2, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v3, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v4, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v5, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v6, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v7, CircleList_Length(list));

        CircleList_Insert(list, (CircleListNode*)&v8, CircleList_Length(list));

       

        for(i=0; i<CircleList_Length(list); i++)

        {

            struct Value* pv = (struct Value*)CircleList_Next(list);

           

            printf("%d ", pv->v);

        }

       

        printf(" ");

       

        CircleList_Reset(list);

       

        while( CircleList_Length(list) > 0 )

        {

            struct Value* pv = NULL;

           

            for(i=1; i<3; i++)

            {

                CircleList_Next(list);

            }

           

            pv = (struct Value*)CircleList_Current(list);

           

            printf("%d ", pv->v);

           

            CircleList_DeleteNode(list, (CircleListNode*)pv);

        }

       

        CircleList_Destroy(list);

       

             return 0;

    }

    3. 游标的定义

    在循环链表中可以定义一个“当前”指针,这个指针通常称为游标,可以通过这个游标来遍历链表中的所有元素。

    4. 循环链表的新操作

    (1)      获取当前游标指向的数据元素。

    (2)      将游标重置指向链表中的第一个数据元素。

    (3)      将游标移动指向到链表中的下一个数据元素。

    (4)      直接指定删除链表中的某个数据元素。

    CircleListNode* CircleList_Current(CircleList* list);

    CircleListNode* CircleList_Reset(CircleList* list);

    CircleListNode* CircleList_Next(CircleList* list);

    CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);

    约瑟夫问题

    n 个人围成一个圆圈,首先第 ,首先第 1 个人从 1 开始一个人一个人顺时针报数,报到第 m 个人,令其出列。然后再从下一 个人开始从 1 顺时针报数,报到第 m 个人,再令其出列,…,如此下去,求出列顺序。

    小结

    l  循环链表只是在单链表的基础上做了一个加强。

    l  循环链表可以完全取代单链表的使用。

    l  循环链表的Next和Current操作可以高效的遍历。

    l  链表中的所有元素。

  • 相关阅读:
    百度mp3地址解密码
    VB 在EXE后附加信息
    截屏函数
    Base64和StrToByte
    The Android ION memory allocator, DMABUF is mentioned as well
    DDC EDID 介绍
    Memory management for graphic processors TTM的由来
    科普 写display driver的必看 How video card works [2D的四种主要操作]
    GEM vs TTM
    DMABUF 背景介绍文章 Sharing buffers between devices
  • 原文地址:https://www.cnblogs.com/free-1122/p/11322743.html
Copyright © 2011-2022 走看看