zoukankan      html  css  js  c++  java
  • python算法与数据结构-循环链表(41)

    一、循环链表的介绍

      上一篇我们已经讲过单链表,本篇给大家讲解循单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点,其基本操作和单链表思路一样。

    常用的操作有

    1. 创建节点
    2. 创建循环链表
    3. 判断是否为空
    4. 头部插入
    5. 循环链表的遍历
    6. 尾部插入
    7. 获取链表长度
    8. 根据下标插入一个节点
    9. 根据下标删除一个节点
    10. 查找是否包含一个节点,并返回其在链表中的位置
    11. 根据下标找节点
    12. 根据下标修改节点的值
    13. 对链表排序

    二、循环链表基本操作的python代码实现

    class Node():
        def __init__(self,num):
            self.element = num
            self.next = None
            
    class CricleLinkList(object):
        def __init__(self):
            self.head = None
            self.length = 0
    
        # 1、判断是否为空
        def is_empty(self):
            if self.head == None:
                return True
            else:
                return False
        
        # 2、头部插入
        def add(self, num):
            # 创建要插入的节点
            node = Node(num)
            if self.is_empty()==True:
                # 如果为空直接插入
                self.head = node
                # 并且把自身的next执行头结点
                node.next = self.head
            else:
                # 将原来的头结点作为插入节点的next
                node.next = self.head
                current = self.head
                # 循坏找到最后一个节点
                while current.next != self.head:
                    current = current.next
                # 将最后一个节点的next执行插入节点
                current.next = node
                # 将插入的节点设置为头结点,完成循坏闭合
                self.head = node
            # 每次添加完成一次,长度加1
            self.length += 1
    
        # 3、遍历
        def travel(self):
            if self.is_empty() == True:
                print("你要遍历的循环链表为空")
                return
            
            print("你要遍历的循环链表元素有:", end=" ")
            current = self.head
            # 先把第一个元素打印一下
            print("%d " % current.element, end=" ")
            # 打印只有一个元素的时候,第一个元素打印不出来,所以先把第一个打印出来
            while current.next != self.head:
                
                current = current.next
                print("%d " % current.element, end=" ")
            print("")
                    
        # 4、尾部插入
        def append(self,num):
            node = Node(num)
            if self.is_empty() == True:
                self.add(num)
            else:
                current = self.head
                while current.next != self.head:
                    current = current.next
                node.next = self.head
                current.next = node
            # 每次添加完成一次,长度加1
            self.length += 1
                
        # 5、指定位置插入
        def insertAtIndex(self,num,index):
            if index<=0 or index>self.length+1:
                print("你要插入的位置不对,请重新选择位置")
                return
            elif self.is_empty() == True:
                self.add(num)
            elif index==1:
                self.add(num)
            elif index == self.length+1:
                self.append(num)
            else:
                current = self.head
                for i in range(index-2):
                    current = current.next
                node = Node(num)
                node.next = current.next
                current.next = node
                
            # 每次添加完成一次,长度加1
            self.length += 1
    
        # 6、按索引删除
        def deleteByIndex(self,index):
            
            if index<=0 or index>self.length:
                print("你要插入的位置不对,请重新选择位置")
                return
            elif self.is_empty() == True:
                print("你要删除的链表为空")
                return
            elif index == 1:
                current = self.head
                for i in range(1,self.length):
                    current = current.next
                current.next = self.head.next
                self.head = self.head.next
            else:
                current = self.head
                for i in range(index-2):
                    current = current.next
                current.next = current.next.next
            # 每次删完长度减1
            self.length -= 1
    
        # 7、查找是否包含,并返回位置
        def isContain(self,num):
            if self.is_empty() == True:
                print("你要查询的链表为空")
                return
            else:
                current = self.head
                for i in range(self.length):
                    if current.element == num:
                        print("你要找到元素在第%d个节点"%(i+1))
                        return i+1
                    current = current.next
                print("没有找到你要的元素")
            return -1
        
        # 8、根据下标找节点
        def searchNodeByIndex(self,index):
            if index<=0 or index>self.length:
                print("你要查询的位置不对,请重新选择位置")
                return
            elif self.is_empty() == True:
                print("你要查询的链表为空")
            else:
                current = self.head
                for i in range(1,index):
                    current = current.next
                print("你要查找%d位置上的节点的值是%d"%(index,current.element))
                
        # 9、根据下标修改节点的值
        def modifyByIndex(self,index,num):
            if index <= 0 or index > self.length:
                print("你要查询的位置不对,请重新选择位置")
                return
            elif self.is_empty() == True:
                print("你要修改的链表为空")
            else:
                current = self.head
                for i in range(1, index):
                    current = current.next
                current.element = num
                
        # 10、排序
        def sort(self):
            if self.length<=0:
                return
            for i in (0,self.length-1):
                current = self.head
                for j in range(0,self.length-i-1):
                    if current.element>current.next.element:
                        temp = current.element
                        current.element = current.next.element
                        current.next.element = temp
                    current = current.next
            
                
    if __name__ == '__main__':
        
        print("======1、创建循环链表 ======")
        cricle_link_list = CricleLinkList()
    
        print("======2、验证是否为空 ======")
        empty = cricle_link_list.is_empty()
        if empty == True:
            print("你查询的链表为空")
        else:
            print("你查询的链表不为空")
        
        print("
    ======3、验证头插和遍历 ======")
        cricle_link_list.add(1)
        cricle_link_list.travel()
        
        print("
    ======4、继续验证头插和遍历 ======")
        cricle_link_list.add(2)
        cricle_link_list.travel()
        
        print("
    ======5、验证尾插 ======")
        cricle_link_list.append(3)
        cricle_link_list.travel()
        
        print("
    ======6、验证按位置插入 ======")
        cricle_link_list.insertAtIndex(0,2)
        cricle_link_list.travel()
        
        print("
    ======7、验证按位置删除 ======")
        cricle_link_list.deleteByIndex(5)
        cricle_link_list.travel()
        
        print("
    ======8、验证查找是否包含元素 ======")
        cricle_link_list.isContain(2)
        
        print("
    ======9、验证根据下标查找元素 ======")
        cricle_link_list.searchNodeByIndex(3)
        
        print("
    ======10、验证修改 ======")
        cricle_link_list.modifyByIndex(3,5)
        cricle_link_list.travel()
        
        print("
    ======11、验证排序 ======")
        cricle_link_list.sort()
        cricle_link_list.travel()
        

    运行结果为:

    ======1、创建循环链表 ======
    ======2、验证是否为空 ======
    你查询的链表为空
    
    ======3、验证头插和遍历 ======
    你要遍历的循环链表元素有: 1  
    
    ======4、继续验证头插和遍历 ======
    你要遍历的循环链表元素有: 2  1  
    
    ======5、验证尾插 ======
    你要遍历的循环链表元素有: 2  1  3  
    
    ======6、验证按位置插入 ======
    你要遍历的循环链表元素有: 2  0  1  3  
    
    ======7、验证按位置删除 ======
    你要插入的位置不对,请重新选择位置
    你要遍历的循环链表元素有: 2  0  1  3  
    
    ======8、验证查找是否包含元素 ======
    你要找到元素在第1个节点
    
    ======9、验证根据下标查找元素 ======
    你要查找3位置上的节点的值是1
    
    ======10、验证修改 ======
    你要遍历的循环链表元素有: 2  0  5  3  
    
    ======11、验证排序 ======
    你要遍历的循环链表元素有: 0  2  3  5  

    三、循环链表基本操作的C语言实现

    //
    //  main.m
    //  循环链表
    //
    //  Created by 侯垒 on 2019/6/27.
    //  Copyright © 2019 可爱的侯老师. All rights reserved.
    //
    
    #include <stdio.h>
    // 创建节点结构体
    typedef struct N
    {
        int element;
        struct N *next;
    }Node;
    
    // 1、创建节点
    Node *createNode(int num)
    {
        Node *node = (Node *)malloc(sizeof(Node));
        node->element = num;
        node->next = NULL;
        return node;
    }
    
    // 2、创建循环链表
    Node *createCricleLinkList(int num)
    {
        Node *head = createNode(num);
        head->next = head;
        return head;
    }
    
    // 3、判断是否为空
    int is_empty(Node *head)
    {
        if (head == NULL)
        {
            return 1;
        }
        return 0;
    }
    
    //4、头部插入
    Node *add(Node *head,int num)
    {
        Node* node = createNode(num);
        Node *current = head;
        if (is_empty(head)==1)
        {
            head = node;
            node->next = head;
        }
        else
        {
            node->next = head;
            while (current->next != head)
            {
                current = current->next;
            }
            current->next = node;
            head = node;
        }
        return head;
    }
    
    // 5、遍历
    void travel(Node *head)
    {
        if (is_empty(head) == 1)
        {
            printf("你遍历的链表为空
    ");
        }
        else
        {
            printf("
    你要遍历的循环链表元素有:");
            Node *current = head;
            printf("%d ",current->element);
            while (current->next != head)
            {
                current = current->next;
                printf("%d ",current->element);
            }
            printf("
    ");
        }
    }
    
    // 5、尾部插入
    Node *append(Node *head,int num)
    {
        Node *node = createNode(num);
        if (is_empty(head)==1)
        {
            add(head, num);
        }
        else
        {
            Node *current = head;
            while (current->next != head)
            {
                current = current->next;
            }
            node->next = head;
            current->next = node;
        }
        return head;
    }
    
    // 6、获取链表长度
    int getLength(Node *head)
    {
        int count = 1;
        Node *current = head;
        if (is_empty(head)==1)
        {
            return 0;
        }
        else
        {
            while (current->next !=head)
            {
                current = current->next;
                count++;
            }
            return count;
        }
    }
    
    // 7、根据下标插入节点
    Node * insertByIndex(Node *head,int num,int index)
    {
        int len = getLength(head);
        if (index<=0||index>len+1)
        {
            printf("你要插入的位置不对,请重新选择位置");
        }
        else if (index == 1)
        {
            head = add(head, num);
        }
        else
        {
            Node *current = head;
            for (int i=1; i<index-1; i++)
            {
                current = current->next;
            }
            Node *node = createNode(num);
            node->next = current->next;
            current->next = node;
        }
        return head;
    }
    
    // 8、根据下标删除
    Node *deleteByIndex(Node *head,int index)
    {
        int len = getLength(head);
        if (index<=0||index>len)
        {
            printf("
    你要删除的位置不对,请重新选择位置");
        }
        else if (index == 1)
        {
            Node *current = head;
            for (int i=1; i<len; i++)
            {
                current = current->next;
            }
            current->next = head->next;
            head = head->next;
        }
        else
        {
            Node *current = head;
            for (int i=0; i<index-2; i++)
            {
                current = current->next;
            }
            current->next = current->next->next;
        }
        return head;
    }
    
    // 9、查找是否包含,并返回位置
    int isContain(Node *head,int num)
    {
        int len = getLength(head);
        Node *current = head;
        for (int i= 0; i<len; i++)
        {
            if (current->element == num)
            {
                return i+1;
            }
            current=current->next;
        }
        return 0;
    }
    
    // 10、根据下标找节点
    Node *searchNodeByIndex(Node *head,int index)
    {
        Node *current = head;
        int len = getLength(head);
        if (index<=0||index>len)
        {
            printf("
    你要查询的位置不对,请重新选择位置");
        }
        else
        {
            
            for (int i =1 ; i<index; i++)
            {
                current = current->next;
            }
            printf("
    你要查找的%d位置上的值为%d",index,current->element);
        }
        return current;
    }
    
    // 11、根据下标修改节点的值
    void modefyByIndex(Node *head,int index,int num)
    {
        Node *current = head;
        int len = getLength(head);
        if (index<=0||index>len)
        {
            printf("
    你要修改的位置不对,请重新选择位置");
        }
        else
        {
            for (int i =1 ; i<index; i++)
            {
                current = current->next;
            }
            current->element = num;
        }
    }
    
    // 12、排序
    void sort(Node *head)
    {
        int len = getLength(head);
        if (len<=0)
        {
            return;
        }
        for (int i = 0; i<len-1; i++)
        {
            Node *current = head;
            for (int j=0; j<len-i-1; j++)
            {
                if (current->element >current->next->element)
                {
                    int temp = current->element;
                    current->element = current->next->element;
                    current->next->element = temp;
                }
                current = current->next;
            }
        }
    }
    
    int main(int argc, const char * argv[])
    {
        printf("=====1、创建循环链表=====");
        Node *head = createCricleLinkList(1);
        
        printf("
    =====2、验证是否为空=====
    ");
        int empty = is_empty(head);
        if (empty == 1)
        {
            printf("你创建的循环链表为空");
        }
        else
        {
            printf("你创建的循环链表不为空");
        }
        
        printf("
    =====3、验证头插和遍历=====");
        travel(head);
        head =  add(head, 0);
        travel(head);
        
        printf("
    =====4、验证尾插=====");
        head = append(head, 2);
        travel(head);
        
        printf("
    =====5、验证根据下表插入=====");
        head = insertByIndex(head, 3, 2);
        travel(head);
        
        printf("
    =====6、验证根据下表删除=====");
        head = deleteByIndex(head, 3);
        travel(head);
        
        printf("
    =====7、验证是否包含=====");
        int num = 3;
        int index = isContain(head, num);
        if (index != 0)
        {
            printf("
    你查找的数据%d在第%d个位置",num,index);
        }
        else
        {
            printf("
    没有找到你要的数据
    ");
        }
        
        printf("
    =====8、验证根据下标找节点=====");
        searchNodeByIndex(head, 2);
        printf("
    =====9、验证根据下标修改节点值=====");
        modefyByIndex(head,2,4);
        travel(head);
        
        printf("
    =====10、验证排序=====");
        sort(head);
        travel(head);
        
        return 0;
    }

    运行结果为:

    =====1、创建循环链表=====
    =====2、验证是否为空=====
    你创建的循环链表不为空
    =====3、验证头插和遍历=====
    你要遍历的循环链表元素有:1 
    
    你要遍历的循环链表元素有:0 1 
    
    =====4、验证尾插=====
    你要遍历的循环链表元素有:0 1 2 
    
    =====5、验证根据下表插入=====
    你要遍历的循环链表元素有:0 3 1 2 
    
    =====6、验证根据下表删除=====
    你要遍历的循环链表元素有:0 3 2 
    
    =====7、验证是否包含=====
    你查找的数据3在第2个位置
    =====8、验证根据下标找节点=====
    你要查找的2位置上的值为3
    =====9、验证根据下标修改节点值=====
    你要遍历的循环链表元素有:0 4 2 
    
    =====10、验证排序=====
    你要遍历的循环链表元素有:0 2 4 
  • 相关阅读:
    猴子分香蕉
    打鱼晒网
    质数/素数
    三角形-->九九乘法表
    eclipse 导入gradle引入多模块项目,引入eclipse后变成了好几个工程
    linux 命令基础大全
    SQL Server 增加链接服务器
    Postgresql数据库部署之:Postgresql 存在session 会话不能删除数据库
    Postgresql数据库部署之:Postgresql本机启动和Postgresql注册成windows 服务
    Git常用命令使用大全
  • 原文地址:https://www.cnblogs.com/Se7eN-HOU/p/11099974.html
Copyright © 2011-2022 走看看