刷题第一天——链表

各种语言的数据读入代码

有些笔试题需要自己写读入数据的代码,牛客网上可以看到默认的读入数据的代码,可以作为参考。

1.java的读入代码

import java.util.Scanner;
public class Main{
	public static void main(){
		Scanner in = new Scanner(System.in);
		while(in.hasNextInt()){
			int a = in.nextInt();
			System.out.println(a);
		}
	}
}

2.c的读入代码

#include <stdio.h>
int mian(){
	int a,b;
	while(scanf("%d %d",&a,&b)!=EOF){
		printf("%d\n",a);
	}
	return 0;
}

3.python的读入代码

import sys
for line in sys.stdin:
	a=line.split()
	print(int(a[0]))

1.链表

1.1链表基础知识

链表和数组是数据类型中两个重要的基础数据类型,数组是连续存储在内存中的数据结构,而链表是一种非连续、非顺序的存储结构,由一系列的结点构成,每个结点包含数据域和指针域。
head:保存首地址,item:保存数据,next:保存下一结点的地址
单向链表:最后一个结点的指针域指向一个空值
循环链表:最后一个结点的指针域指向头结点,包括单循环列表和双循环列表
双向链表:每个结点有两个指针域,prevnext,分别指向前后
链表的常用方法:增加、删除、查询、修改、遍历

1.2python的链表操作

python不存在指针
新建一个节点类,实现基本功能:更新数据、查询数据、更新后继结点和查询后继结点
新建一个链表类,实现基本功能:增加、查找、删除、是否为空、链表长度
新建一个升序链表类,和链表类就增加、查找、删除操作会有一定的区别

参考

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

    def get_data(self):
        return self.data

    def set_data(self,new_data):
        self.data=new_data

    def get_next(self):
        return self.next

    def set_next(self,new_next):
        self.next=new_next

class Linked_list(object):
    def __init__(self):
        self.head=None

    def add(self,data):  #单链表添加只需要一个指针
        new_node=Node(data)
        new_node.data=data
        new_node.set_next(self.head) #头插法
        self.head=new_node

    def search(self,data):
        checking=self.head
        while checking!=None:
            if checking.get_data()==data:
                return True
            checking=checking.get_next()
        return False

    def remove(self,data):  #删除需要两个指针
        checking=self.head  #从头结点开始查询
        previous=None  #记录前一个结点,头结点为None
        while checking!=None:
            if checking.get_data()==data:
                break
            previous=checking
            checking=checking.get_next()

        if previous==None:  #不存在前驱结点
            self.head=checking.get_next()
        else:
            previous.set_next(checking.get_next())

    def isEmpty(self):
        return self.head==None

    def size(self):
        count=0
        checking=self.head
        while checking!=None:
            count+=1
            checking=checking.get_next()
        return count

#升序链表
class Ordered_linked_list(object):
    def __init__(self):
        self.head=None

    def add(self,data):  #需要两个指针
        checking=self.head
        previous=None
        while checking!=None:
            if checking.get_data()>data:
                break
            previous=checking
            checking=checking.get_next()

        new_node=Node(data)
        if previous==None: #插入头结点
            new_node.set_next(self.head)
        else:
            previous.set_next(new_node)
            new_node.set_next(checking)
    def search(self,data):
        checking=self.head
        while checking!=None:
            if checking.get_data()==data:
                return True
            elif checking.get_data>data:
                return False
            checking=checking.get_next()
        return False

    def remove(self,data):
        checking=self.head
        previous=None
        while checking!=None:
            if checking.get_data()==data:
                break
            previous=checking
            checking=checking.get_next()

        if previous==None:
            self.head=checking.get_next()
        else:
            previous.set_next(checking.get_next())

1.3python实现栈和队列

参考
栈:先进后出

# 构建了一个长度无限的栈
class Stack:
    def __init__(self):
        self.stack = []
 
    def push(self, element):
        return self.stack.append(element)
 
    def pop(self):
        if self.is_empty():
            raise IndexError("Stack is empty")
        else:
            return self.stack.pop()
 
    def get_top(self):
        if self.is_empty():
            raise IndexError("Stack is empty")
        else:
            return self.stack[-1]  # 输出表尾
 
    def is_empty(self):
        if len(self.stack) == 0:
            return True  # 是空栈
        else:
            return False
 
 
if __name__ == "__main__":
    init_stack = Stack()
    init_stack.stack = [1, 2, 3, 4, 5]
    init_stack.push(6)  # 进栈:6
    init_stack.pop()    # 出栈:6
    for items in init_stack.stack:
        print(items)    # 栈的遍历

队列:先进先出

# deque是一个双向队列,可以实现队首队尾出队、队首队尾入队
from collections import deque
def in_de_queue():
    queue = deque([1, 2, 3])    # 实例化,创建对象queue
    queue.pop()  # 队尾出队(3)
    queue.append(4)  # 队尾入队(4)
    queue.appendleft([7, 8, 9])  # 队首入队([7,8,9])
    queue.appendleft(6)  # 队首入队(6)
    queue.popleft()  # 队首出队(6)
    print(queue)

1.4java的链表操作

java有一个LinkedList(链表)类,是一种常用的数据容器,是一个双向链表,定义了nextprev两个指针
相较于ArrayListLinkedList的增加和删除操作效率更高,然而查找和修改的操作效率较低。
LinkedList类位于java.util包里面,需要import java.util.LinkedList;

//java的源代码
 private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
    
//自定义的Node
 public class ListNode{
        int val;
        ListNode next=null;
        public ListNode(int val){
            this.val=val;
        }
    }

LinkList<String> sites = new LinkList<String>();

//增加
private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        size++;
        modCount++;
    }

    /**
     * Links e as last element.
     */
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

//删除
public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

//查询
public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

//修改
public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
    }


//遍历
for(int i=0;i<sites.size();i++){
   System.out.println(sites.get(i));
}
        
for(String i:sites){
   System.out.println(i);
}
        
Iterator iter=sites.iterator();
while (iter.hasNext()){
   System.out.println(iter.next());
}    

1.5java链表的应用:队列和栈

队列:先进先出
栈:先进后出


//队列
LinkedList list = new LinkedList();
list.add("Java");  //入队
list.poll();  //出队

public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

//栈
LinkedList list = new LinkedList();
list.add("Java"); //进栈
list.pollLast(); //出栈

public E pollLast() {
        final Node<E> l = last;
        return (l == null) ? null : unlinkLast(l);
    }

 private E unlinkLast(Node<E> l) {
        // assert l == last && l != null;
        final E element = l.item;
        final Node<E> prev = l.prev;
        l.item = null;
        l.prev = null; // help GC
        last = prev;
        if (prev == null)
            first = null;
        else
            prev.next = null;
        size--;
        modCount++;
        return element;
    }

1.6反转链表-java

参考
1.使用Stack(栈)

public ListNode reverseList(ListNode head) {
    if (head == null) return null;
    Stack<ListNode> stack = new Stack<>();
    stack.push(head); // 存入第一个节点
    while (head.next != null) {
        stack.push(head.next); // 存入其他节点
        head = head.next; // 指针移动的下一位
    }
    // 反转链表
    ListNode listNode = stack.pop(); // 反转第一个元素
    ListNode lastNode = listNode; // 临时节点,在下面的 while 中记录上一个节点
    while (!stack.isEmpty()) {
        ListNode item = stack.pop(); // 当前节点
        lastNode.next = item;
        lastNode = item;
    }
    lastNode.next = null; // 最后一个节点赋为null(不然会造成死循环)
    return listNode;
}

2.递归

public static ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) return head;
    // 从下一个节点开始递归
    ListNode reverse = reverseList(head.next);
    head.next.next = head; // 设置下一个节点的 next 为当前节点
    head.next = null; // 把当前节点的 next 赋值为 null,避免循环引用
    return reverse;
}

3.循环

class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null) return null;
        // 最终排序的倒序链表
        ListNode prev = null;
        while (head != null) {
            // 循环的下个节点
            ListNode next = head.next;
            // 反转节点操作
            head.next = prev;
            // 存储下个节点的上个节点
            prev = head;
            // 移动指针到下一个循环
            head = next;
        }
        return prev;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值