数据结构-循环单链表

循环列表

实现一个循环链表

  • is_empty() 链表是否为空
  • length() 链表长度
  • travel() 遍历整个链表
  • append(item) 链表尾部添加元素
  • add(item) 链表头部添加元素
  • insert(pos, item) 指定位置添加元素
  • search(item) 查找节点是否存在
  • remove(item) 节点删除
    先实现一个节点
class CircleNode(object):
    # 循环链表节点
    def __init__(self, item):
        # 用来存储数据
        self.item = item
        # 存储下一个节点数据的地址
        self.next = None

循环链表的实现
因为跟单链表有很多相似的地方,所以先附上代码,后面加入分析过程

class CircleNode(object):
    # 循环链表节点
    def __init__(self, item):
        # 用来存储数据
        self.item = item
        # 存储下一个节点数据的地址
        self.next = None
class CircleLinkList(object):
    def __init__(self, node = None):
        # 空链表self._head = None
        # 非空,1个节点,自己指向自己
        self._head = node
        if node:
            node.next = node
    
    def is_empty(self):
        # 判断列表是否为空
        return self._head == None 

    def length(self):
        '''链表的长度'''
        if self._head == None:
            return 0
        cur = self._head
        # 如果count = 0最后一个节点不会被计入,也可以采用返回值+1的方式
        count = 1
        while cur.next != self._head:
            count += 1
            cur = cur.next
        return count
    
    def travel(self):
        '''遍历链表'''
        if self.is_empty():
            return None
        cur = self._head
        while cur.next != self._head:
            print(cur.item, end=' ')
            cur = cur.next
        print(cur.item)
        print(' ')

    def append(self, item):
        '''尾部添加'''
        node = CircleNode(item)
        if self.is_empty():
            self._head = node
            node.next = node
        else:
            cur = self._head
            while cur.next != self._head:
                cur = cur.next
            cur.next = node
            node.next = self._head

    def add(self, item):
        '''头部添加'''
        node = CircleNode(item)
        if self.is_empty():
            self._head = node
            node.next = node
        
        cur = self._head
        while cur.next != self._head:
            cur = cur.next
        cur.next = node
        node.next = self._head
        self._head = node

    def insert(self, pos, item):
        '''指定位置添加元素'''
        node = CircleNode(item)
        if pos < 0:
            self.add(item)
        elif pos > self.length():
            self.append(item)
        else:
            cur = self._head
            count = 0
            while count < (pos - 1):
                cur = cur.next
                count += 1
            node.next = cur.next
            cur.next = node

    def search(self, item):
        '''查询某个值在链表中是否存在'''
        if self.is_empty():
            return None
        cur = self._head
        while cur.next != self._head:
            if cur.item == item:
                return True
            else:
                cur = cur.next
        if cur.item == item:
            return True
        else:
            return False
    
    def remove(self, item):
        '''删除节点'''
        if self.is_empty():
            return None
        cur = self._head
        pre = None
        # 如果要删除的是第一个节点
        if cur.item == item:
            # 循环链表中不只一个节点
            if cur.next != self._head:
                while cur.next != self._head:
                    cur = cur.next
                cur.next = self._head.next
                self._head = cur.next
            # 循环链表中只有一个节点
            else:
                self._head = None
        # 删除中间或尾部节点
        else:
            while cur.next != self._head:
                if cur.item == item:
                    pre.next = cur.next
                    return
                else:
                    pre = cur
                    cur = cur.next
            if cur.item == item:
                pre.next = self._head
        

c = CircleLinkList()
print(c.is_empty())
print(c.length())

c.append(9)
# c.append(2)
# c.append(1)
c.add(6)
c.add(5)
c.add(4)
c.add(3)

c.insert(7, 200)
c.travel()
c.remove(4)
c.travel()
print(c.search(520))

在这里插入图片描述
is_empty()&length()&travel()
is_empty():只需关注开头,_head指向了空,它就是空链表,若非空,就不是空链表,无需关注链表有多长
length(): 引入一个游标(指针),指针往后移动一次,count就加1,注意如果count起始值为0,那返回的count需要加1。注意空列表的情况
travel(): 也需要一个游标,让游标循环,游标指向哪里就打印哪里。注意空列表的情况
在这里插入图片描述
append()

append(): 尾部添加,先让尾节点指向新节点,再让新节点指向头结点即可。如果是空节点,_head指向新节点,新节点指向自己。

在这里插入图片描述
add()

add(): 头部添加,通过循环找到最后一个节点,尾结点指向新节点,新节点指向原头结点,_head指向新节点。若是空链表,_head指向新节点,新节点指向自己。
在这里插入图片描述
insert()

insert():分三种情况,中间插入,头插,尾插
中间插入,如图,根据pos和count定位到要插入位置,让新节点指向后面,cur指向新节点,
尾插,与append同理
头插,与add同理。
注意空链表

search()
与便利类似

remove()

在这里插入图片描述
remove中间节点:通过cur和pre两个指针,cur定位到要删除的节点,pre指向cur前一个节点,pre.next直接指向cur.next,就跳过了要删除的节点,即实现删除的效果。
在这里插入图片描述
remove最后节点:如果一直没有找到要删除的节点,while循环后,cur停留在尾结点,需要单独判别尾结点是否是需要删除的节点,是-删除
在这里插入图片描述
remove头节点
头节点有分两种情况
链表长度大于1,先循环链表(因为我们需要用到最后一个节点),如果cur指向的节点与我们传入的相同,即删除第一个节点,让尾结点指向self._head.next,再让_head指向cur.next
链表长度等于1,_head直接指向None

单链表是一种常见的数据结构,它由一个或多个节点组成,每个节点包含一个数据域和一个指针域,指针域指向下一个节点。 实现单链表的查找位序算法函数需要以下步骤: 1. 定义一个指针p指向链表的头节点,并定义一个变量count,用于计数。 2. 从头节点开始,遍历链表,当p指向某个节点时,计数器count加1。 3. 如果p指向的节点的数据与目标数据相等,则返回当前的计数器count,即为目标数据的位序。 4. 如果p指向的节点不是目标数据,则将p指向下一个节点,重复步骤3。 5. 如果遍历完链表后仍未找到目标数据,则返回-1,表示未找到。 下面是C语言实现单链表查找位序算法函数的代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义单链表节点结构 typedef struct Node { int data; // 数据域 struct Node* next; // 指针域 } Node; // 查找位序的算法函数 int findPosition(Node* head, int target) { Node* p = head; // 指向头节点 int count = 0; // 计数器初始化为0 while (p != NULL) { count++; // 计数器加1 if (p->data == target) { return count; // 找到目标数据,返回当前计数器的值 } p = p->next; // 指向下一个节点 } return -1; // 遍历完链表未找到目标数据,返回-1 } int main() { // 创建链表 Node* head = (Node*)malloc(sizeof(Node)); head->data = 1; // 头节点数据为1 Node* node1 = (Node*)malloc(sizeof(Node)); node1->data = 2; Node* node2 = (Node*)malloc(sizeof(Node)); node2->data = 3; head->next = node1; node1->next = node2; node2->next = NULL; // 查找位序示例 int target = 3; // 目标数据为3 int position = findPosition(head, target); if (position != -1) { printf("目标数据 %d 的位序为 %d\n", target, position); } else { printf("未找到目标数据 %d\n", target); } // 释放链表内存 free(node2); free(node1); free(head); return 0; } ``` 在上述代码中,我们首先定义了一个指向头节点的指针p和一个计数器count,然后使用while循环遍历链表。当p指向某个节点时,计数器加1,并判断该节点的数据是否与目标数据相等。如果找到了目标数据,则返回当前计数器的值,即为目标数据的位序。如果遍历完链表仍未找到目标数据,则返回-1表示未找到。最后在主函数中演示了调用该算法函数的示例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值