Python implements linear table

Definition of linear table

A linear table is a finite sequence of n (n.>=0) data elements with the same data type, where n is the length of the table, and n=0 means the table is an empty table, generally expressed as:
L=(a1, a2...an-1,an)
Logical characteristics: a1 is the header element, and an is the footer element. Except for the header element, each element has one and only one direct predecessor. Except for the footer element, each element has and only There is a direct successor.
Features of linear tables:
-The number of elements in the table is limited.
– The elements in the table are logically sequential, and the elements in the sequence are arranged in their order.
– The elements in the table are all data elements, and each element is a single element.
– The data types of the elements in the table are the same, that is, the storage space occupied by each element is the same.
A linear table is a logical structure that represents a one-to-one neighbor relationship between elements. Sequence list and linked list are storage structures, and they belong to different levels of concepts.
**

Sequence table

**: The sequential storage structure of the linear table uses a group of storage units with consecutive addresses to store the data elements in the linear table in sequence, so that the two logically adjacent elements are also adjacent in physical position, that is, the sequence table The logical order is the same as its physical order.
The following figure is the sequence table expressed in C language, and sizeof() is used to calculate the storage space occupied by the element.

There are two ways to implement the sequence table:
Insert picture description here

Figure a shows an integrated structure. The unit for storing table information and the element storage area are arranged in a storage area in a continuous manner. The two parts of data form a complete sequence table object as a whole. The one-piece structure has strong integrity and is easy to manage. But because the data element storage area is a part of the table object, after the sequence table is created, the element storage area is fixed.

Figure b shows a separated structure. Only the information (capacity and number of elements) related to the entire table is stored in the table object. The actual data elements are stored in another independent element storage area and are associated with the basic table object through links.
In the official implementation of Python, list is a dynamic sequence table implemented with a separate technology. Use list to insert and delete, and there is no need to move the elements behind the element in sequence like C language. Simple code implementation:

class mysqlist():
    def __init__(self,size):
        self.size=size
        self.sqlist=[]
    def listinsert(self,i,x):
        if i<1 or i>self.size:
            print("Insert Location Error!")
            return False
        else:
            self.sqlist.insert(i,x)
            return True
    def listdelete(self,i):
        if i<1 or i>self.size:
            print("Delete Location Error!")
            return False
        else:
            self.sqlist.pop(i)
            return False
    def findelem(self,i):
        if i<1 or i>self.size:
            print("search Location Error!")
            return False
        else:
            return self.sqlist[i]
    def showlist(self):
        return self.sqlist

import random
testsqlist=mysqlist(10)
for i in range(1,12):
    testsqlist.listinsert(i,i*100)
print("插入元素后的顺序表为:",testsqlist.showlist())
for i in range(1,2):
    testsqlist.listdelete(i)
print("删除元素后的顺序表为:",testsqlist.showlist())
print(testsqlist.findelem(5))

The output of the code is:

Insert Location Error!
插入元素后的顺序表为: [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
删除元素后的顺序表为: [100, 300, 400, 500, 600, 700, 800, 900, 1000]
700

Single list

The chain storage of linear tables is a non-random access storage structure. Store the data elements of the linear table through a set of arbitrary storage units. In order to establish the linear relationship between the data elements, for each linked list node, in addition to storing the information of the element itself, it is also necessary to store a pointer to its successor. .
Insert picture description here
First define a linked list without a head node, **self.head is the head pointer, pointing to the first data element. **When the head pointer is "NULL", it means an empty table.

class linknode():#每个结点有两个数据成员,结点元素和指向下一个结点的指针
    def __init__(self,item):
        self.item=item
        self.next=None
class  linklist():#初始化单链表,头指针指针域为空
    def __init__(self):
        self.head=None    

There are two ways to create a singly linked list, head interpolation and tail interpolation: the
head interpolation creates a singly linked list, starting from an empty list, generating a new node, and storing the read data in the data field of the new node , And then insert the new node into the head of the current linked list, that is, after the head pointer:

    def headcreatlist(self, item):
        nod = linknode(item)  # 新建一个结点并赋值
        nod.next = self.head  # 结点指针域指向第一个结点
        self.head = nod  # 头指针指向当前结点

The tail interpolation method is to insert a new node into the end of the current linked list, and a tail pointer needs to be added to make it always point to the end node of the current linked list.

    def tailcreatelist(self, item):
        nod = linknode(item)  # 新建一个结点并赋值,指针域为None
        cur = self.head
        while cur != None:  # 遍历到最后一个元素,指针域为None
            cur = cur.next
        cur.next = nod  # nod成为最后一个结点

List some other methods:

	#判断是否为空
    def is_empty(self):
        return self.head == None

    def listlength(self):
        nod = self.head  # 头结点指针域指向第一个结点
        nodnum = 0
        while (nod != None):
            nodnum += 1
            nod = nod.next  # 下一个结点
        return nodnum
        # 遍历单链表

    def tralist(self):
        show=[]
        nod = self.head
        while nod != None:
            show.append(nod.item)
            nod = nod.next
        return show

        # 在指定位置插入元素,插入位置为1~length+1,pos==1表示头插法,pos==length+1表示尾插法
        # 找到插入位置的前驱结点,再在其后插入新结点

    def Insertlist(self, pos, item):
        if pos < 1 or pos > self.listlength() + 1:
            print("Insert Position Error!")
            return False
        elif pos == 1:
            self.headcreatlist(item)
        elif pos == self.listlength() + 1:
            self.tailcreatelist(item)
        else:
            nod = linknode(item)
            count = 0
            cur = self.head
            while (count < pos - 1):
                cur = cur.next
                count += 1
            nod.next = cur.next
            cur.next = nod


    # 删除指定位置的结点
    def delete(self, pos):
        if pos < 1 or pos > self.listlength():
            print("Position Error!")
            return False
        else:
            nod=self.head
            coun=0
            while coun<pos-1:
                nod=nod.next
                coun+=1
            ne=nod.next.next
            nod.next=ne



        # 根据位置获取元素
    def Getelembypos(self, pos):
        if pos < 1 or pos > self.listlength():
            print("Position Error!")
            return False
        else:
            cur = self.head
            count = 1
            while count < pos:
                cur = cur.next
                count += 1
            return cur.item

     # 根据结点元素获取结点(保证获取的值唯一)
    def getposbyelem(self, elem):
        cur = self.head
        while (cur != None and cur.item != elem):
            cur = cur.next
        return cur if cur.item == elem else None

Combine the above codes and call the function to test:

if __name__ == "__main__":
    ll1=linklist()
    for i in range(10):
        ll1.headcreatlist(i*10)

    len=ll1.listlength()
    print("单链表的长度为:",len)
    sh=ll1.tralist()
    print("头插法建立的链表遍历为:",ll1.tralist())

    # ll2 = linklist()
    for i in range(10):
        ll1.tailcreatelist(i * 100)

    len = ll1.listlength()
    print("单链表的长度为:", len)
    sh = ll1.tralist()
    print("尾插法插法建立的链表遍历为:", ll1.tralist())
    ll1.Insertlist(1,111111)
    ll1.Insertlist(1,111111)
    print("插入元素后的链表遍历为:", ll1.tralist())
    ll1.deleteelem(1)
    ll1.deleteelem(2)
    print("删除元素后的链表遍历为:", ll1.tralist())

    print("第二个位置上的元素为:",ll1.Getelembypos(2))

The output is:

单链表的长度为: 10
头插法建立的链表遍历为: [90, 80, 70, 60, 50, 40, 30, 20, 10, 0]
单链表的长度为: 20
尾插法插法建立的链表遍历为: [90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0, 100, 200, 300, 400, 500, 600, 700, 800, 900]
插入元素后的链表遍历为: [111111, 111111, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0, 100, 200, 300, 400, 500, 600, 700, 800, 900]
删除元素后的链表遍历为: [111111, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0, 100, 200, 300, 400, 500, 600, 700, 800, 900]
第二个位置上的元素为: 80

There will be a problem here. If the table is built directly by the tail insertion method, an error will be reported if there is no element in the table: AttributeError:'NoneType' object has no attribute'next' The
error statement is:
while cur.next != None: # 遍历到最后一个元素,指针域为空
This is because the tail insertion method is inserted when the linked list is created. For an element, self.head points to the first element, which is None at this time, so there is no next attribute, and an error will naturally be reported.
Therefore, the first node needs special processing, and we generally avoid this special processing by increasing the head node. If you are interested, you can learn about it: Python implements singly linked list (lead node)

Guess you like

Origin blog.csdn.net/liulanba/article/details/113720473