数据结构学习之线性表

线性表

线性表,是由若干个数据特性相同的元素的组成有限序列。

根据实现方式的不同,可以分为顺序表链表,顺序表依据结构的差异,可以分为一体式分离式两种;链表可以分为单向链表双向链表环形链表

本文以python编程的方式,对各种数据结构进行描述和实现。

顺序表

顺序表的结构可以分为表头和数据区两部分。

表头用于描述表的信息,表头信息通常包括表容量、已使用情况(当前表成员数量),如果是分离式结构(python中列表list为这种结构),还会包括数据区的首地址。
在这里插入图片描述
上图为分离式顺序表结构,表结构中3表示表长度,其中已包含两个表成员10和11,数据区的首地址为0x12,每个方块表示存储单元,根据数据类型的不同而占据不同的空间大小,具体需要参考C语言中对整形、字符和浮点等基本数据类型的大小规定。

对于python列表,用于表示列表的变量指向了顺序表的表头首地址,当执行append方法增加元素到列表尾部时,其表头首地址不变,而是改变数据区的数据(数据区首地址随着发生变化),这时只需改变表头中指向数据区的地址(0x12)即可,所以执行append方法的前后其(变量)id是不变的。

a=[1,2,3]
id(a) # 返回 45213256L
a.append(22)
id(a) # 返回 45213256L

python中的元组是典型的一体式顺序表,其结构如下:

在这里插入图片描述

链表

链表是由若干个节点首尾相连组成的,节点由数据区和指针域(链接区)组成,链接区用于储存下一个节点的地址,末尾节点的链接区为空(None)。
单链表:指针域只有一个后向指针;
在这里插入图片描述

双链表:指针域由一个后向指针和一个前向指针组成;
在这里插入图片描述

环形链表:链表尾部节点的后向指针指向链表头部节点,构成一个环形链表

这里以 单链表为例说明数据结构的python实现。

首先定义节点类 Node:

class Node():
    def __init__(self, item):
        # data
        self.item = item
        # probe
        self.next = None

然后定义单链表类 single_table,类私有属性为链表的首节点地址 self.__head,实现链表长度(length方法)查询,是否为空(empty方法),列表的元素遍历(itersall方法),元素搜索(search方法)、任意位置插入(insert方法)和删除(remove方法,删除表中第一个指定元素)。

class single_table():
    def __init__(self, node = None):
        # head probe
        self.__head = node
    def empty(self):
        return self.__head == None
    def length(self):
        count=0
        cur=self.__head
        while cur:
            count += 1
            cur=cur.next
        return count
    def itersall(self):
        if self.empty():
            return
        cur=self.__head
        while cur:
            print(cur.item,' ,', end='')
            cur=cur.next
        print('')
    def add(self, item):
        node=Node(item)
        if self.empty():
            self.__head=node
            return
        node.next=self.__head
        self.__head=node
    def append(self, item):
        node=Node(item)
        cur=self.__head
        if not cur:
            self.add(item)
            return
        while cur.next:
            cur=cur.next
        cur.next=node
    def insert(self, pos, item):
        node=Node(item)
        if pos <= 0:
            self.add(item)
        elif pos > self.length()-1:
            self.append(item)
        else:
            cur=self.__head
            while pos>1:
                cur=cur.next
                pos -= 1        
            node.next=cur.next
            cur.next=node
    def search(self, item):
        cur=self.__head
        #pos=0
        while cur:
            if cur.item ==item:
                return True
            cur=cur.next
            #pos += 1
        return False
    def remove(self, item):
        pre=self.__head
        # empty
        if not pre:
            return
        cur=pre.next
        # only 1 element
        if not cur:
            if pre.item ==item:
                self.__head = None
            return
        while cur:
            if pre.item ==item:
                if pre == self.__head:
                    self.__head=cur
                else:
                    pre.next=cur.next
                break
            elif cur.item ==item:
                if cur.next:
                    pre.next=cur.next
                else:
                    pre.next=None              
                break
            pre=pre.next
            cur=pre.next


对于环形链表,这里以环形单链表为例,通过python代码实现,与上面的单链表比较,差别主要在于 首尾节点互联,实现的方法是相同的,仅做少量修改。

class Node():
    def __init__(self, item):
        # data
        self.item = item
        # probe
        self.next = None


class singleCYC_table():
    def __init__(self, node = None):
        # head probe
        self.__head = node
        if node:
            node.next = node
    def empty(self):
        return self.__head == None
    def length(self):
        if self.empty():
            return 0
        count=1
        cur=self.__head
        while cur.next != self.__head:
            count += 1
            cur=cur.next
        return count
    def itersall(self):
        if self.empty():
            return
        cur=self.__head
        while cur.next != self.__head:
            print(cur.item,' ,', end='')
            cur=cur.next
        print(cur.item,' ,', end='')
        print('')
    def add(self, item):
        node=Node(item)
        if self.empty():
            self.__head=node
            node.next = node
            return
        node.next=self.__head
        cur=self.__head
        while cur.next != self.__head:
            cur=cur.next     
        cur.next=node
        self.__head=node
    def append(self, item):
        node=Node(item)
        if self.empty():
            self.__head=node
            node.next = node
            return
        cur=self.__head
        while cur.next != self.__head:
            cur=cur.next
        cur.next = node
        node.next = self.__head
    def insert(self, pos, item):
        node=Node(item)
        if pos <= 0:
            self.add(item)
        elif pos > self.length()-1:
            self.append(item)
        else:
            cur=self.__head
            while pos>1:
                cur=cur.next
                pos -= 1        
            node.next=cur.next
            cur.next=node
    def search(self, item):
        cur=self.__head
        if not cur:
            return False
        #pos=0
        while cur.next != self.__head:
            if cur.item ==item:
                return True
            cur=cur.next
        if cur.item ==item:
            return True
        return False
    def remove(self, item):
        pre=''
        cur=self.__head
        # empty
        if not cur:
            return
        # only 1 element
        if self.length() == 1:
            if cur.item ==item:
                self.__head = None
            return
        # more than 2 elements, 1st match
        if cur.item ==item:
            tmp=self.__head
            while tmp.next != self.__head:
                tmp=tmp.next
            self.__head=cur.next
            tmp.next=self.__head
            return
        # search 2th and after
        while cur.next != self.__head:
            if cur.item ==item:
                pre.next=cur.next
                return
            pre=cur
            cur=cur.next
        #last one check
        if cur.item ==item:
            pre.next = self.__head


最后补充下 双向链表的实现:
定义 节点类 如下:

class Node():
    def __init__(self, item):
        # previous node address
        self.pre = None
        # data
        self.item = item
        # probe
        self.next = None

以节点为基础,定义双向链表类及对应方法。

class double_table():
    def __init__(self, node = None):
        # head probe
        self.__head = node
    def empty(self):
        return self.__head == None
    def length(self):
        if self.empty():
            return 0
        count=1
        cur=self.__head
        while cur.next != None:
            count += 1
            cur=cur.next
        return count
    def itersall(self):
        if self.empty():
            return
        cur=self.__head
        while cur.next != None:
            print(cur.item,' ,', end='')
            cur=cur.next
        print(cur.item,' ,', end='')
        print('')
    def add(self, item):
        node=Node(item)
        if self.empty():
            self.__head=node
            return
        self.__head.pre=node
        node.next=self.__head
        self.__head=node
    def append(self, item):
        node=Node(item)
        if self.empty():
            self.__head=node
            return
        cur=self.__head
        while cur.next != None:
            cur=cur.next
        node.pre=cur
        cur.next = node
    def insert(self, pos, item):
        node=Node(item)
        if pos <= 0:
            self.add(item)
        elif pos > self.length()-1:
            self.append(item)
        else:
            cur=self.__head
            while pos>0:
                cur=cur.next
                pos -= 1
            cur.pre.next=node
            node.pre=cur.pre
            node.next=cur
            cur.pre=node
    def search(self, item):
        cur=self.__head
        if not cur:
            return False
        #pos=0
        while cur.next != None:
            if cur.item ==item:
                return True
            cur=cur.next
        if cur.item ==item:
            return True
        return False
    def remove(self, item):
        cur=self.__head
        # empty
        if not cur:
            return
        # only 1 element
        if self.length() == 1:
            if cur.item ==item:
                self.__head = None
            return
        # more than 2 elements, 1st match
        if cur.item ==item:
            self.__head=cur.next
            cur.next.pre=None
            return
        # search 2th and after
        while cur.next != None:
            if cur.item ==item:
                cur.next.pre=cur.pre
                cur.pre.next=cur.next
                return
            cur=cur.next
        #last one check
        if cur.item ==item:
            cur.pre.next = None

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值