列表、堆栈、队列

目录 

一、列表

1.1 线性表的顺序存储

1.1.1 动态顺序表 

1.1.2 MyArrayList(Java)

1.1.3 SequentialList(Python)

1.2 双向列表

1.2.1 特点

1.2.2 MyLinkedList(Java)

1.2.3 DoublyLinkedList(Python)

二、堆栈

1、定义

1.1 Java版

1.2 python版

1.3 使用两个队列实现一个栈

三、队列

1、定义

1.1、两个栈实现一个队列


一、列表

1.1 线性表的顺序存储

1.1.1 动态顺序表 

        线性表的顺序存储是把线性表的数据元素按逻辑次序依次存放在一组连续的存储单元中,即逻辑结构上相邻的两个数据元素存储在计算机内的物理存储位置也是相邻的,这种存储方法为整个线性表分配一整个内存块保存线性表的元素

优缺点:

        优点:快速访问元素

        缺点:插入元素的成本比较大

动态顺序表的结构:

        属性:固定长度的数组、数组的最大长度、数组中实际元素的个数

        函数:

                基本功能:初始化、返回列表的长度、扩充数组的容量、是否包含某元素、将列表转为字符串输出、判断两个数组是否相等

                扩展功能:在索引位置上get/set、返回指定元素的索引位置、追加、插入、删除、

1.1.2 MyArrayList(Java)

package com.ssmCombine.LeetCode;

import java.util.Iterator;

public class MyArrayList<AnyType> implements Iterable<AnyType>{

   private static final int DEFAULT_CAPACITY = 10;

   private int theSize;
   private AnyType[] theItems;

   public MyArrayList(){
       doClear();
   }
   public void clear(){
       doClear();
   }
   public void doClear(){
       theSize = 0;
       ensureCapacity(DEFAULT_CAPACITY);
   }

   public int size(){
       return theSize;
   }

   public boolean isEmpty(){
       return size() == 0;
   }

   public void trimToSize(){
       ensureCapacity(size());
   }

   public AnyType get(int idx){
       if (idx < 0 || idx >= size()){
           throw new ArrayIndexOutOfBoundsException();
       }
       return theItems[idx];
   }

   public AnyType set(int idx, AnyType newVal){
       if (idx < 0 || idx >= size()){
           throw new ArrayIndexOutOfBoundsException();
       }
       AnyType old = theItems[idx];
       theItems[idx] = newVal;
       return old;
   }

   public void ensureCapacity(int newCapacity){
       if (newCapacity < theSize)
           return;

       AnyType[] old = theItems;
       theItems = (AnyType[]) new Object[newCapacity];
       for (int i = 0; i < size(); i++) {
           theItems[i] = old[i];
       }
   }

   public void add(int idx, AnyType x){
       if(theItems.length == size()){
           ensureCapacity(size() * 2 + 1);
       }
       for (int i = theSize; i > idx; i--) {
           theItems[i] = theItems[i - 1];
       }
       theItems[idx] = x;
       theSize++;
   }

   public boolean add(AnyType x){
       add(size(), x);
       return true;
   }

   public AnyType remove(int idx){
       AnyType removedItem = theItems[idx];
       for (int i = idx; i < size() - 1; i++) {
           theItems[i] = theItems[i + 1];
       }
       theSize--;
       return removedItem;
   }

   public Iterator<AnyType> iterator() {
       return (Iterator<AnyType>) new ArrayListIterator();
   }

   public class ArrayListIterator implements Iterable<AnyType>{
       private int current = 0;

       public boolean hasNext(){
           return current < size();
       }
       
       public AnyType next(){
           if(!hasNext())
               throw new java.util.NoSuchElementException();
           return theItems[current++];
       }
       
       public void remove(){
           MyArrayList.this.remove(--current);
       }
       
       @Override
       public Iterator<AnyType> iterator() {
           return null;
       }
   }
}

1.1.3 SequentialList(Python)

class SequentialList:
    def __init__(self, max_size=10):
        self.items = [None] * max_size
        self.num_items = 0
        self.max_size = max_size

    def __len__(self):
        return self.num_items

    def __getitem__(self, index):
        if index >= 0 and index < self.num_items:
            return self.items[index]
        raise IndexError('SequentialList index out of range')

    def __setitem__(self, index, val):
        if index >= 0 and index < self.num_items:
            self.items[index] = val
            return
        raise IndexError("SequentialList assignment index out of range")

    def locate(self, item):
        for i in range(self.num_items):
            if self.items[i] == item:
                return i
        raise ValueError("{} is not in sequential list".format(item))

    def __alloc(self):
        new_size = (self.max_size // 4) + self.max_size + 1
        new_items = [None] * new_size
        for i in range(self.num_items):
            new_items[i] = self.items[i]

        self.items = new_items
        self.max_size = new_size

    def append(self, item):
        if self.num_items == self.max_size:
            self.__alloc()

        self.items[self.num_items] = item
        self.num_items += 1

    def insert(self, index, item):
        if self.num_items == self.max_size:
            self.__alloc()
        if index < self.num_items and index >= 0:
            for j in range(self.num_items - 1, index - 1, -1):
                self.items[j + 1] = self.items[j]
            self.items[index] = item
            self.num_items += 1
        elif index >= self.num_items:
            self.append(item)
        else:
            raise IndexError("SequentialList assignment index out of range")

    def __delitem__(self, index):
        for i in range(index, self.num_items - 1):
            self.items[i] = self.items[i + 1]
        self.num_items -= 1

    def __str__(self):
        s = '['
        for i in range(self.num_items):
            s += repr(self.items[i])
            if i < self.num_items - 1:
                s += ', '
        s += ']'
        return s

    def __contains__(self, item):
        for i in range(self.num_items):
            if self.items[i] == item:
                return True
        return False

    def __eq__(self, another):
        if type(another) != type(self) or self.num_items != another.num_items:
            return False
        for i in range(self.num_items):
            if self.items[i] != another.items[i]:
                return False
        return True


if __name__ == "__main__":
    sample_sqlist = SequentialList()
    sample_sqlist.append(11)
    sample_sqlist.append(22)
    sample_sqlist.append(33)

    print('顺序表数据元素为:', sample_sqlist)
    print('顺序表长度:', len(sample_sqlist))
    print('顺序表中第0个数据元素:', sample_sqlist[0])
    # 修改数据元素
    sample_sqlist[1] = 2022
    print('顺序表数据元素为:', sample_sqlist)

    print('在顺序表位置1处添加元素2021')
    sample_sqlist.insert(1, 2021)
    print('添加元素后,顺序表数据元素为:', sample_sqlist)
    print('删除顺序表位置2处元素')
    del (sample_sqlist[2])
    print('删除数据后,顺序表数据元素为:', sample_sqlist)
    print('元素11的索引为{}'.format(sample_sqlist.locate(11)))
    print('11在顺序表中?', 11 in sample_sqlist)
    print('22在顺序表中?', 22 in sample_sqlist)

        

1.2 双向列表

1.2.1 特点

        双向链表对于元素的添加、删除操作的开销是比较小的,只需要改变元素的前向、后向指针所指引的内容即可

        双向链表的结构:

                自定义节点类:包括当前节点的内容、前向节点(节点实例本身)、后向节点

                属性:链表的头节点、尾节点、链表的长度

                方法:

                        清空:构造头结点、尾节点,并使其相连,长度置为0

                        返回链表的长度、判断是否为空

                        获取索引位置的节点、更新索引节点的内容、在索引位置处添加新节点、删除节点

1.2.2 MyLinkedList(Java)

package com.ssmCombine.LeetCode;

import java.util.Iterator;

public class MyLinkedList<AnyType> implements Iterable<AnyType> {

    private static class Node<AnyType>{

        public AnyType data;
        public Node<AnyType> prev;
        public Node<AnyType> next;

        public Node(AnyType d, Node<AnyType> p, Node<AnyType> n){
            data = d;
            prev = p;
            next = n;
        }
    }

    private int theSize;
    private int modCount = 0;
    private Node<AnyType> beginMarker;
    private Node<AnyType> endMarker;

    public MyLinkedList(){
        doClear();
    }

    public void doClear(){
        theSize = 0;
        modCount++;
        beginMarker = new Node<AnyType>(null, null, null);
        endMarker = new Node<AnyType>(null, beginMarker, null);
        beginMarker.next = endMarker;
    }

    public void clear(){
        doClear();
    }

    public int size(){
        return theSize;
    }

    public boolean isEmpty(){
        return size() == 0;
    }

    private void addBefore(Node<AnyType> p, AnyType x){
        Node<AnyType> newNode = new Node<>(x, p.prev, p);
        newNode.prev.next = newNode;
        p.prev = newNode;
        theSize++;
        modCount++;
    }

    private Node<AnyType> getNode(int idx, int lower, int upper){
        Node<AnyType> p;

        if(idx < lower || idx > upper){
            throw new IndexOutOfBoundsException();
        }

        if(idx < size() / 2){
            p = beginMarker.next;
            for (int i = 0; i < idx; i++) {
                p = p.next;
            }
        } else {
          p = endMarker;
            for (int i = size(); i > idx ; i--) {
                p = p.prev;
            }
        }
        return p;
    }

    public void add(int idx, AnyType x){
        addBefore(getNode(idx, 0, size()), x);
    }

    public boolean add(AnyType x){
        add(size(), x);
        return true;
    }
    
    private Node<AnyType> getNode(int idx){
        return getNode(idx, 0, size() - 1);
    }
    
    public AnyType get(int idx){
        return getNode(idx).data;
    }
    
    public AnyType set(int idx, AnyType newVal){
        Node<AnyType> p =getNode(idx);
        AnyType oldVal = p.data;
        p.data = newVal;
        return oldVal;
    }
    
    private AnyType remove(Node<AnyType> p){
        p.next.prev = p.prev;
        p.prev.next = p.next;
        theSize--;
        modCount++;
        
        return p.data;
    }
    
    public AnyType remove(int idx){
        return remove(getNode(idx));
    }
    
    @Override
    public Iterator<AnyType> iterator() {
        return null;
    }
}

1.2.3 DoublyLinkedList(Python)

"""
    Node:新的结构类型->节点
    data:数据
    previous:前一个节点
    next:后一个节点
"""


class Node:
    def __init__(self, data=None):
        self.data = data
        self.next = None
        self.previous = None

    def __str__(self):
        return str(self.data)
"""
    双向链表的python实现
    https://www.jb51.net/article/235210.htm
"""
import CreateNode


# node = CreateNode.Node(5)
# print(node.__str__())

class DoublyLinkedList:
    def __init__(self):
        self.length = 0
        self.head = CreateNode.Node()

    def __len__(self):
        return self.length

    def __getitem__(self, index):
        if index > self.length - 1 or index < 0:
            raise IndexError("DoublyLinkedList assignment index out of range")
        else:
            count = -1
            current = self.head
            while count < index:
                count += 1
                current = current.next
            return current.data

    def __setitem__(self, index, value):
        if index > self.length - 1 or index < 0:
            raise IndexError("DoublyLinkedList assignment index out of range")
        else:
            count = -1
            current = self.head
            while count < index:
                current = current.next
                count += 1
            current.data = value

    def locate(self, value):
        count = -1
        current = self.head
        while current != None and current.data != value:
            count += 1
            current = current.next
        if current and current.data == value:
            return count
        else:
            raise ValueError("{} is not in sequential list".format(value))

    def insert(self, index, data):
        count = 0
        prev = self.head
        if index > self.length or index < 0:
            raise IndexError("DoublyLinkedList assignment index out of range")
        else:
            new_node = CreateNode.Node(data)
            while count < index:
                prev = prev.next
                count += 1
            new_node.previous = prev
            self.length += 1
            if prev.next:
                new_node.next = prev.next
                prev.next.previous = new_node
                prev.next = new_node
            else:
                prev.next = new_node

    def get_node(self, index):
        count = -1
        current = self.head
        if index > self.length - 1 or index < 0:
            raise IndexError("DoublyLinkedList assignment index out of range")
        while count < index:
            current = current.next
            count += 1
        return current

    def __delitem__(self, index):
        if index > self.length - 1 or index < 0:
            raise IndexError("DoublyLinkedList assignment index out of range")
        else:
            current = self.get_node(index)
            if current:
                current.previous.next = current.next
            if current.next:
                current.next.previous = current.previous
            self.length -= 1
            del current

    def __str__(self):
        s = "["
        current = self.head.next
        count = 0
        while current != None:
            count += 1
            s += str(current)
            current = current.next
            if count < self.length:
                s += '<-->'
        s += "]"
        return s

    def del_value(self, value):
        current = self.head
        while current:
            if current.data == value:
                current.previous.next = current.next
                if current.next:
                    current.next.previous = current.previous
                self.length -= 1
                del current
                return
            else:
                current = current.next
        raise ValueError("The value provided is not present!")

    def append(self, data):
        new_node = CreateNode.Node(data)
        current = self.head
        while current.next:
            current = current.next
        current.next = new_node
        new_node.previous = current
        self.length += 1


if __name__ == "__main__":
    dllist = DoublyLinkedList()
    # 在链表末尾追加元素
    dllist.append('apple')
    dllist.append('banana')
    dllist.append('orange')
    # 在指定位置插入元素
    dllist.insert(0, 'grape')
    dllist.insert(4, 'lemon')
    print('双向链表 sllist 为:', dllist)
    print('双向链表 sllist 长度为:', len(dllist))
    print('双向链表 sllist 第0个元素为:', dllist[0])
    # 修改数据元素
    dllist[0] = 'pear'
    del (dllist[3])
    print('双向修改链表 sllist 数据后:', dllist)
    # 修改数据元素
    dllist[0] = 'pear'
    print('修改双向链表 dllist 数据后:', dllist)
    dllist.insert(0, 'watermelon')
    print('在位置 0 添加 watermelon 后双向链表链表 ddlist 数据:', dllist)
    del (dllist[3])
    print('删除位置 3 处元素后双向链表 ddlist 数据:', dllist)
    dllist.append('lemon')
    print('在尾部追加元素 lemon 后双向链表 ddlist 数据:', dllist)
    # dllist.del_value('lemon')
    # print('删除 lemon 后双向链表 dllist 数据:', dllist)
    # print('watermelon 在双向链表 dllist 中的索引为:', dllist.locate('orange'))

二、堆栈

1、定义

        栈是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫作栈的顶(top),对栈的进本操作有进栈(push)和出栈(pop),最后插入的元素可通过使用 top 在执行 pop 之前进行考查,LIFO(后进先出)

1.1 Java版

package com.ssmCombine.LeetCode;

import java.util.Arrays;

public class MyStack<T> {

    // 实现栈的数组
    private Object[] stacks;
    // 栈的容量
    private int size;

    public MyStack() {
        stacks = new Object[10];  // 初始容量设置为10;
    }

    // 判断是否为空
    public Boolean isEmpty(){
        return size == 0;
    }

    // 返回栈顶元素,但不弹出
    public T peek(){
        if (size > 0) {
            return (T) stacks[size - 1];
        } else {
            return null;
        }
    }

    // 出栈操作
    public T pop(){
        T t = peek();
        if (size > 0) {
            stacks[size - 1] = null;
            size--;
        }
        return t;
    }

    // 入栈操作
    public Boolean push(T t){
        expandCapacity(size + 1);
        stacks[size] = t;
        size++;
        return true;
    }

    /// 判断容量大小是否够用
    private void expandCapacity(int n){
        if(n > stacks.length){
            n = n * 3 / 2 + 1;
            stacks = Arrays.copyOf(stacks, n);
        }
    }

}

1.2 python版

"""
    1、自定义堆栈
"""


class MyselfStock:
    def __init__(self):
        self.items = []
        self.current = 0

    def push(self, item):
        self.items.append(item)
        self.current += 1

    def pop(self):
        item = self.items.pop()
        self.current -= 1
        return item

    def top(self):
        return self.items[self.current - 1]

    def empty(self):
        return self.current == 0


if __name__ == '__main__':
    s = MyselfStock()
    s.push(1)
    s.push(2)
    s.push(3)
    print(s.top())
    print(s.pop())
    print(s.top())
    print(s.empty())

1.3 使用两个队列实现一个栈

python版

from collections import deque


class MyStack:
    def __init__(self):
        self.deque1 = deque()
        self.deque2 = deque()

    def push(self, x: int):
        self.deque1.append(x)
        while self.deque2:
            self.deque1.append(self.deque2.popleft())
        self.deque2, self.deque1 = self.deque1, self.deque2

    def pop(self):
        return self.deque2.popleft()

    def top(self):
        return self.deque2[0]

    def empty(self):
        return not self.deque2


if __name__ == '__main__':
    st = MyStack()
    st.push(5)
    st.push(3)
    st.push(7)
    st.push(8)
    st.push(1)
    print(st.empty())
    print(st.top())
    st.pop()
    print(st.pop())


三、队列

1、定义

        队列也是一种表,LILO(先进先出),基本操作有入队、出队

1.1、两个栈实现一个队列

package com.ssmCombine.LeetCode;

import java.util.LinkedList;
import java.util.Stack;

/**
 * 使用两个 栈 实现 一个队列
 */

public class MyQueue {

    private Stack stack1;
    private Stack stack2;

    public MyQueue(){
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }

    public void appendTail(int value) {
        stack1.push(value);
    }

    public int deleteHead() {
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return (int) stack2.pop();
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值