3.数据结构-链表

动态数组有个明显的缺点,有可能会造成内存空间的大量浪费,能否用到多少就申请多少内存?

链表可以办到这一点,链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的.

 

 单向链表实现(Java)

package zh.datastructures.LinkedList;


public class LinkedList<T> {

        private int foot; // 根节点索引位置
        private int count; // 代表链表程度
        private Node root; // 标识根节点

        // 链接点类,内部方法实现,外部使用
        private class Node {

            private T data; // 数据信息
            private Node next; // 下一个节点引用

            public Node(T data) {
                this.data = data;
            }

            // 添加节点
            private void add(T data) {
                if (this.next == null) {
                    this.next = new Node(data); // 如果当前节点的next为null,直接创建一个新的节点
                } else {
                    this.next.add(data); // 否则进行递归调用,直到最后在某个为空的节点创建一个新节点
                }
            }

            // 删除节点1
            public void remove(Node previous, int index) {

                if (LinkedList.this.foot++ == index) {
                    previous.next = this.next; // this表示当前要删除的节点
                    this.next = null;
                    LinkedList.this.count--;
                    return;
                } else {
                    this.next.remove(this, index); // 递归删除
                }

            }

            // 删除节点2
            public void remove(Node previous, T data) {
                if (this.data.equals(data)) {
                    previous.next = this.next;
                    this.next = null;
                    LinkedList.this.count--;
                    return;
                } else {
                    if (this.next != null) {
                        this.next.remove(this, data);
                    } else {
                        return;
                    }
                }
            }

            // 修改数据 -- 新数据替换旧数据
            public void replace(T oldData, T newData) {
                if (this.data.equals(newData)) {
                    this.data = newData;
                } else {
                    this.next.replace(oldData, newData); // 递归修改,寻找当前节点下一个节点,直到某个节点的值匹配入参
                }

            }

            // 修改数据 -- 利用索引修改
            public void replace(int index, T newData) {
                if (LinkedList.this.foot++ == index) { // 找到了某个值的索引和传入的索引相同,直接替换
                    this.data = newData;
                } else {
                    this.next.replace(index, newData);
                }
            }

            // 查询
            public T get(int index) {
                if (LinkedList.this.foot++ == index) {
                    return this.data;
                } else {
                    return this.next.get(index);
                }
            }

            // 链表是否包含某个节点
            public boolean contains(T data) {
                if (this.data.equals(data)) { // 如果当前的这个data正好和传入的data匹配
                    return true;
                } else {
                    // 如果当前的这个不匹配,则需要查找下一个节点
                    if (this.next == null) {
                        return false;
                    } else {
                        return this.next.contains(data);
                    }
                }
            }

        }

        public LinkedList() {

        }

        // 检查链表是否为空
        public boolean isEmpty() {
            if (count == 0 || this.root == null) {
                return true;
            } else {
                return false;
            }
        }

        // 获取链表的长度
        public int size() {
            return this.count;
        }

        // 添加
        public void add(T data) {
            if (this.isEmpty()) { // 如果链表为空,新建一个节点
                this.root = new Node(data);
            } else {
                this.root.add(data);
            }
            this.count++;
        }

        // 删除 -- 按照索引删除
        public void remove(int index) {
            if (this.isEmpty()) {
                return;
            }
            if (index < 0 || this.count <= index) {
                return;
            }
            if (index == 0) { // 想要删除根节点
                Node temp = this.root;
                this.root = this.root.next;
                temp.next = null;
                this.count--;
                return;
            } else {
                this.foot = 0;
                this.root.remove(this.root, index);
            }
        }

        // 根据传入的数值删除
        public void remove(T data) {
            if (this.isEmpty()) {
                return;
            }
            if (this.root.data.equals(data)) { // 如果删除的正好是根节点
                Node temp = this.root;
                this.root = this.root.next;
                temp.next = null;
                this.count--;
                return;
            } else {
                this.root.remove(this.root, data);
            }
        }

        // 修改 -- 根据索引修改
        public void replace(int index, T newData) {
            if (this.isEmpty()) {
                return;
            }
            if (index < 0 || this.count <= index) {
                return;
            }
            this.foot = 0;
            this.root.replace(index, newData);
        }

        // 修改 -- 新老数据替换
        public void replace(T oldData, T newData) {
            if (this.isEmpty()) {
                return;
            }
            this.root.replace(oldData, newData);
        }

        // 查询 --- 根据索引查找
        public T get(int index) {
            if (this.isEmpty()) {
                return null;
            }
            this.foot = 0;
            return this.root.get(index);
        }

        // 是否包含
        public boolean contains(T data) {
            if (this.isEmpty()) {
                return false;
            }
            return this.root.contains(data);
        }

        // 打印 toArray
        public Object[] toArray() {
            if (this.isEmpty()) {
                return null;
            }
            int count = this.count;
            Object[] retVal = new Object[count];
            for (int i = 0; i < count; i++) {
                retVal[i] = this.get(i);
            }
            return retVal;
        }
    }

双向链表实现

class Node:
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.prev = None
        self.next = None

    def __str__(self):
        val = '{}:{}'.format(self.key,self.value)
        return val

    def __repr__(self):
        val = '{}:{}'.format(self.key,self.value)
        return val


class DoubleLinkedList:
    def __init__(self, capacity=0xffff):
        self.capacity = capacity
        self.head = None
        self.tail = None
        self.size = 0

    #从头部添加
    def __add_head(self,node):
        if not self.head:
            self.head= node
            self.tail=node
            self.head.next=None
            self.head.prev=None
        else:
            node.next=self.head
            self.head.prev=node
            self.head=node
            self.head.prev=None
        self.size +=1
        return node

    #从尾部添加
    def __add_tail(self,node):
        if not self.tail:
            self.head=node
            self.tail=node
            self.prev=None
            self.next=None
        else:
            node.prev=self.tail
            self.tail.next=node
            self.tail=node
            self.tail.next=None
        self.size +=1
        return node

    #从尾部删除
    def __del_tail(self):
        if not self.tail:
            return
        node=self.tail
        if node.prev:
            self.tail= node.prev
            self.tail.next=None
        else:
            self.tail=self.head=None
        self.size -=1
        return node

    #从头部删除
    def __del_head(self):
        if not self.head:
            return
        node = self.head
        if node.next:
            self.head=node.next
            self.head.prev=None
        else:
            self.tail=self.head=None
        self.size -=1
        return node
    #任意节点删除
    def __remove(self,node):
        #如果node=None,默认删除尾部节点
        if not node:
            node=self.tail
        if node ==self.tail:
            self.__del_tail()
        elif node ==self.head:
            self.__del_head()
        else:
            node.prev.next=node.next
            node.next.prev=node.prev
        self.size -=1
        return node

     #弹出头部节点
    def pop(self):
        return self.__del_head()

    #添加节点
    def append(self,node):
        return self.__add_tail(node)

    #从头部添加节点
    def append_front(self,node):
        return self.__add_head(node)

    #删除节点
    def remove(self,node=None):
        return self.__remove(node)

    def print(self):
        p=self.head
        line=''
        while p:
            line +='{}'.format(p)
            p=p.next
            if p:
                line +='=>'
        print(line)

//测试代码
if __name__ == '__main__': l =DoubleLinkedList(10) nodes=[] for i in range(10): node=Node(i,i) nodes.append(node) l.append(nodes[0]) l.print() l.append(nodes[1]) l.print() l.pop() l.print() l.append(nodes[2]) l.print() l.append_front(nodes[3]) l.print() l.append(nodes[4]) l.print() l.remove(nodes[2]) l.print() l.remove() l.print()

单向循环链表实现

双向链表实现

静态链表

posted @ 2020-05-23 20:55  大碗炸酱面  阅读(129)  评论(0编辑  收藏  举报