Python and C + + implement single chain table

Posted by Gugel on Sun, 05 Jan 2020 18:40:08 +0100

Algorithm and data structure are the basis of programming. Recently, I started to learn Python. When learning a new language, I reviewed the data structure I learned a long time ago. The nature of data structure implementation is not related to language.

Implementation point of single chain table:

1. When initializing the linked list, the header node can define only the pointer field and not the data field, or directly define the pointer field and the data field of the header node in the initialization list (C + +).

2. Insert single chain table:

The insertion operation of single chain table is relatively simple, as shown in the figure above, p2 is the insertion pointer, 2Node is the insertion node, direct p2 - > next = head - > next, head - > next = p2.

3. Delete single chain table:

Take the above figure as an example. To delete the 2Node node from the right figure to the left, just head - > next = P1

Insertion and deletion need to take into account the position of the node (chain header, chain tail), and the creation of auxiliary variables in C + + during the structure decomposition, otherwise, there will be the problem of pointer hanging (wild pointer).

Python implementation

'''Operation of single chain table
is_empty() Whether the list is empty
length() Length of linked list
travel() Traverse the entire list
add(data) Add elements to the head of the list
append(data) Add elements at the end of the list
insert(pos, data) Add element at specified location
remove(data) Delete node
find(data) Find whether the node exists'''
class SingleNode(object):
    """Node of single chain table"""
    def __init__(self,data):
        # _Data stores data elements
        self.data = data
        # _Next is the identification of the next node
        self.next = None


class SingleLinkList(object):
    """Single linked list"""
    def __init__(self):
        self._head = None

    def is_empty(self):
        """Judge whether the list is empty"""
        return self._head == None

    def length(self):
        p = self._head
        count = 0
        while p != None:
            count += 1
            p = p.next
        return count

    def travel(self):
        p=self._head
        while p!=None:
            print(p.data," ")
            p=p.next

    def add(self,data):
        item = SingleNode(data)
        item.next = self._head
        self._head = item

    def append(self,data):
        item = SingleNode(data)
        if self.is_empty():
            self.add(data)
        else:
            p=self._head
            while p.next!=None:
                p=p.next
            item.next=p.next
            p.next=item

    def find(self,data):
        '''The more direct idea is to locate data The node, but the single chain table cannot be located quickly data So go back p.next.data==d Of p Pointer'''
        p=self._head
        while p.next:
            if p.next.data==data:
                return p
            p=p.next
        return None

    def insert(self,pos,data):
        if pos <= 0:
            self.add(data)
            # If the specified position exceeds the end of the list, the end insertion is performed
        elif pos > (self.length() - 1):
            self.append(data)
            # Find the specified location
        else:
            item = SingleNode(data)
            p=self._head
            for i in range (1,pos):
                p=p.next
            item.next=p.next
            p.next=item

    def remove(self,data):
        h = self._head
        if h.data == data:
            self._head = h.next
        else:
            if not self.find(data):
                print("Not found!Please change your data!")
                return
            else:
                p = self.find(data)
                q = p.next
                p.next = q.next

if __name__ == "__main__":
    ll = SingleLinkList()
    ll.add(1)
    ll.add(2)
    ll.append(3)
    ll.travel()
    ll.insert(2, 4)
    print ("length:",ll.length())
    ll.travel()
    ll.remove(2)
    print ("length:",ll.length())
    ll.travel()

C++ implementation

#include <iostream>
using namespace std;

class List {
public:
	List(){create_List();}
	~List(){clear();}

	//Function declaration
	void create_List();
	//Insert from head node
	void insert(const int& d);
	//Insert at specified location
	void insert_pos(const int&d,const int&d1);
	//Delete the node of the specified data
	void erase(const int& d);
    //Modify specified data
    void updata(const int& d,const int& d1);
    //Reverse linked list function
    void reverse();
	void reverse_print();

	
    //Printing
    void print();
    //Node structure
    struct Node{
		int data;
		Node* next;
		Node(const int& d):data(d),next(NULL){}
       
    };


    Node * head;//Header node
    //Clean up linked list functions
	//Reverse print
	void ReversePrint(Node* head);
    void clear(){
        //Loop delete from the beginning of the node
      //      Will delete p;//delete delete the corresponding value, or just transfer the memory control to the system like free?
        //    p = q; / / the first sentence cannot be commented out, then delete p, and assign the value of p - > next to p. pointer hanging is inevitable
	
          Node* p =head;
		  while(p)
		  {
			  Node* q =p->next;
			  delete p;
			  p=q;
		  }
        //You need to be very careful when deleting the pointer to avoid the problem of pointer hanging.
    }
    //Function to find the last node position of data d
    //For the convenience of later deletion
    Node* find(const int& d){
       Node *p =head;
	   while (p){
		   if(p->next->data==d)
			   break;
		   p=p->next;
	   }
		return p;
    }
};

//Create head node
void List::create_List()
{
     head = new Node(0);
}
//Insert a node from the beginning, assign its own successor first, then the successor of its previous element, and declare the definition outside the class
void List::insert(const int& d)
{
    Node* q =new Node(d);
	q->next=head->next;
	head->next=q;

}
//Print function
void List::print()
{
	Node* p =head->next;
	while(p)
	{
		cout<<p->data<<endl;
		p=p->next;
	}
    
}
//Insert d1 before position d
void List::insert_pos(const int& d,const int& d1)
{
	Node* p =find(d);
	Node* q = new Node(d1);
	q->next=p->next;
	p->next=q;

}

//Delete the node whose data is a value
void List::erase(const int& d)
{
	Node* p = find(d);
	Node* q = p->next;
	p->next=q->next;

    
}

//Modify specified data
void List::updata(const int& d,const int& d1)
{
  Node* p = find(d);
  p->next->data=d1;
}

//Inverted list
void List::reverse()
{
    Node * p = head->next;//The first node after the head node
    Node * q = p->next;//The second node after the head node
    Node * m = q->next;//The third node after the head node
    p->next = NULL;//Set the next pointer of the first node after the head contact to null
    //Judge each node in reverse order according to whether m is empty
    while(m){
        q->next = p;
        p = q;
        q = m;
        m = m->next;
    }
    //Reverse the last node
    q->next = p;
    //Point the head from the new node to the new node 1 (the last previous node)
    head ->next = q;
}

void List::reverse_print()
{
	ReversePrint(head->next);
}

void List::ReversePrint(Node *head)//Recursively print in reverse order (without changing the linked list structure). It is awkward to output the default data value of the header node, which is 0,
//Because of the use of recursive calls, it is not convenient to modify the code body. When passing parameters, you can use - > next to move backward one bit, because it is not a sequential storage structure,
//So head + + can't be used
{  
    if(head!=NULL)  
    {  
        if(head->next!=NULL)  
            ReversePrint(head->next);  
        cout<<head->data<<endl;  
    }  
}  

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

    // insert code here...
    List list;
    list.insert(30);
    list.insert(20);
    list.insert(10);
//	list.insert(40);
    list.insert_pos(10, 5);
    list.print();
    cout << "---------------------" << endl;
    list.erase(10);
    list.print();
    cout << "---------------------" << endl;
    list.reverse();
    list.print();
    cout << "---------------------" << endl;
    list.updata(5, 8);
    list.print();
	cout << "---------------------" << endl;
	//list.reverse_print();
    return 0;
}

The picture is referenced in the following blog:

https://www.cnblogs.com/leaver/p/6718421.html

Topics: Python Programming