The implementation of the go language of the doubly linked list

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

First, what is a doubly linked list

And the single-linked list, the elements of the two-way list not only know their downline, but also know their online (more and more like the MLM organization). The small coal car to open, the figure can be seen, each compartment in addition to a point to the back of the car's arrows, there is a pointing to the front of the car's arrows (head, car tail except). The front only points to the rear compartment of the arrow, the rear of the car only pointed to the arrow.

Two, two-way linked list and go of the corresponding structure

1. Node

Let's break down the compartment first. Each compartment is composed of 4 parts: coal, bodywork, pull-up carriages, ropes, pull-back carriages. The car body is our transportation tool, in the go language we use the structure to raise the dnode to represent, the coal represents the cargo which transports, uses the data variable to express, pulls the front carriage rope and the pull back carriage rope we respectively use the pointer prev and next to indicate. Such a carriage, in the go language is described as follows:

type DNode struct { data Object prev *DNode next *DNode}

2. Doubly linked list

A coal-truck fleet is a doubly linked list. The team has to have the front, car, tail, as the head of the team also need to know how long the team. In the go language, the team with the structure of the dlist, the car head with a variable, the parking space with the tail variable, the length of the fleet is expressed in size, the expression together:

type DList struct { size uint64 head *DNode tail *DNode}

The structure is finished, the following talk about how to increase, reduce the carriage, that is, the interface of the doubly linked list.

Third, the interface description and implementation

The interface is mainly divided into these categories. One is the doubly linked list itself, and the other is the node. The list itself is also divided into public and private two kinds. Let's talk about these interfaces in more detail below.

1. Initialize the list of links init

Two-way list initialization, it can be understood that Chengdawei ready to buy a team ready to transport coal. The first step, to obtain the approval of the State authorities, with the approval of the Davido can buy the car to transport coal. But when it was approved, brother David's motorcade had nothing, no front, no tail, no car. Go Language code implementation:

func (dList *DList) Init() { _dList := *(dList) _dList.size = 0     // 没车厢 _dList.head = nil   // 没车头 _dList.tail = nil   // 没车尾}

2. New Data Append

David Brother bought a new car, and bought the car to hang behind the team. The first compartment is the front.

func (dList *DList) Append(data Object) {    newNode := new(DNode)    (*newNode).data =  data    if (*dList).GetSize() == 0 { // 买个车头        (*dList).head = newNode        (*dList).tail = newNode        (*newNode).prev = nil        (*newNode).next = nil    } else { //  挂在车队尾部        (*newNode).prev = (*dList).tail        (*newNode).next = nil        (*((*dList).tail)).next = newNode        (*dList).tail = newNode    }    (*dList).size++;}

3. Insert data behind the node Insertnext

Sometimes, the carriages are not placed in the tail of the motorcade, but in the middle, for example, it is best to put together an apple carriage.

func (dList *DList) InsertNext(elmt *DNode, data Object) bool {    if elmt == nil { // apend        return false       }    if dList.isTail(elmt) { // 恰好在车队尾巴        dList.Append(data)    } else {        newNode := new(DNode)        (*newNode).data =  data        (*newNode).prev = elmt        (*newNode).next = (*elmt).next        (*elmt).next = newNode        (*((*newNode).next)).prev = newNode        (*dList).size++;    }    return true}

5. Insert data in front of the node Insertprev

Inserting data in front of a node can be understood as inserting data behind a node before the current node.

func (dList *DList) InsertPrev(elmt *DNode, data Object) bool {    if elmt == nil {        return false    }    if dList.isHead(elmt) {  // 如果是新增一个车头就特殊处理        newNode := new(DNode)        (*newNode).data = data        (*newNode).next = dList.GetHead()        (*newNode).prev = nil        (*(dList.head)).prev = newNode        dList.head = newNode        dList.size++        return true    } else {        prev := (*elmt).prev        return dList.InsertNext(prev, data)    }}

The ishead here is to determine whether the node is the front, David introduction.
6. Delete a node remove
Some carriages are in trouble and need to be repaired, so they must be removed from the convoy.

func (dList *DList) Remove(elmt *DNode) Object {    if elmt == nil {        return false    }    prev := (*elmt).prev    next := (*elmt).next    if dList.isHead(elmt) {        dList.head = next    } else {        (*prev).next = next    }    if dList.isTail(elmt) {        dList.tail = prev    } else {        (*next).prev = prev    }    dList.size--    return (*elmt).GetData() }

After unloading, the data in the compartment is still to be retained.

7. Find the node where the specified data is located search

For example, find out which compartment the apple is in. It is necessary to use the search function.

func (dList *DList) Search(data Object, yourMatch ...MatchFun) *DNode {    if dList.GetSize() == 0 {        return nil    }    match := defaultMatch    if len(yourMatch) > 0 {        match = yourMatch[0]    }    node := dList.GetHead()    for ; node != nil; node = node.GetNext() {        if match(node.GetData(), data) == 0 {            break        }    }    return node}

Match is a matching function, defined as follows:

type MatchFun func (data1 Object, data2 Object) int

If data1 and data2 are equal, returns 0,data1 greater than Data2 and returns a positive number, less than a negative number.

8, get the link table length GetSize

func (dList *DList) GetSize() uint64 { return (*dList).size}

9. node GetHead

func (dList *DList) GetHead() *DNode { return (*dList).head}

10, get the tail node GetTail

func (dList *DList) GetTail() *DNode { return (*dList).tail}

11, whether the node is the head node Ishead

func (dList *DList) isHead(elmt *DNode) bool { return dList.GetHead() == elmt}

12, whether the node is the tail of the list Istail

func (dList *DList) isTail(elmt *DNode) bool { return dList.GetTail() == elmt}

13. Get the data GetData in the node

func (dNode *DNode) GetData() Object { return (*dNode).data}

This is the method of the node, not the linked list. Used to get what's inside the compartment.
14. Get the next node GetNext

func (dNode *DNode) GetNext() *DNode { return (*dNode).next}

This is also a node method to help the car find the next compartment.
15. Get the previous node GetPrev

func (dNode *DNode) GetPrev() *DNode { return (*dNode).prev}

Here is also the method of the node. Used to find the last compartment.

Code download

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.