自己做网站需要什么程序,网站站内推广计划书,一个服务器做多个网站,红网常德论坛#来自ウルトラマンティガ#xff08;迪迦#xff09; 1 线性表 最基本、最简单、最常用的一种数据结构。一个线性表是 n 个具有相同特性的数据元素的有限序列。
特征#xff1a;数据元素之间是一对一的逻辑关系。
第一个数据元素没有前驱#xff0c;称为头结点#xff1…#来自ウルトラマンティガ迪迦 1 线性表 最基本、最简单、最常用的一种数据结构。一个线性表是 n 个具有相同特性的数据元素的有限序列。
特征数据元素之间是一对一的逻辑关系。
第一个数据元素没有前驱称为头结点最后一个数据元素没有后继称为尾结点除了头结点和尾结点其他数据元素有且仅有一个前驱和一个后继。
分类
顺序存储链式存储
2 顺序表 顺序表是在计算机内存中以数组的形式保存的线性表线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素。
public class SequenceListT implements IterableT {//存储元素的数组private T[] eles;//记录当前顺序表中的元素个数private int N;//构造方法public SequenceList(int capacity) {//初始化数组this.eles (T[]) new Object[capacity];//初始化长度this.N 0;}//将一个线性表置为空表public void clear() {this.N 0;}//判断当前线性表是否为空表public boolean isEmpty() {return N 0;}//获取线性表的长度public int length() {return N;}//获取指定位置的元素public T get(int i) {return eles[i];}//向线型表中添加元素 tpublic void insert(T t) {if (N eles.length) {resize(2 * eles.length);}eles[N] t;}//在 i 元素处插入元素 tpublic void insert(int i, T t) {if (N eles.length) {resize(2 * eles.length);}//先把i索引处的元素及其后面的元素依次向后移动一位for (int index N; index i; index--) {eles[index] eles[index - 1];}//再把t元素放到i索引处即可eles[i] t;//元素个数1N;}//删除指定位置i处的元素并返回该元素public T remove(int i) {//记录索引i处的值T current eles[i];//索引i后面元素依次向前移动一位即可for (int index i; index N - 1; index) {eles[index] eles[index 1];}//元素个数-1N--;if (N eles.length / 4) {resize(eles.length / 2);}return current;}//查找t元素第一次出现的位置public int indexOf(T t) {for (int i 0; i N; i) {if (eles[i].equals(t)) {return i;}}return -1;}//根据参数newSize重置eles的大小public void resize(int newSize) {//定义一个临时数组指向原数组T[] temp eles;//创建新数组eles (T[]) new Object[newSize];//把原数组的数据拷贝到新数组即可for (int i 0; i N; i) {eles[i] temp[i];}}Overridepublic IteratorT iterator() {return new SIterator();}private class SIterator implements Iterator {private int cursor;public SIterator() {this.cursor 0;}Overridepublic boolean hasNext() {return cursor N;}Overridepublic T next() {return eles[cursor];}}
}
复杂度
get(i)时间复杂度 O(1)
insert(int i, T t)时间复杂度 O(n)
remove(int i)时间复杂度 O(n)
3 链表 链表是一种物理存储单元上非连续、非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列的结点链表中的每一个元素称为结点组成结点可以在运行时动态生成。
//链表结点
public class NodeT { //存储元素 public T item; //指向下一个结点 public Node next; public Node(T item, Node next) { this.item item;this.next next; }
}
复杂度
get(i)时间复杂度 O(n)
insert(int i, T t)时间复杂度 O(1)
remove(int i)时间复杂度 O(1)
3.1 单向链表 单向链表是链表的一种它由多个结点组成每个结点都由一个数据域和一个指针域组成数据域用来存储数据指针域用来指向其后继结点。链表的头结点的数据域不存储数据指针域指向第一个真正存储数据的结点。
public class LinkListT implements IterableT {//头结点private Node head;//链表的长度private int N;//结点类private class Node {//存储数据T item;//下一个结点Node next;public Node(T item, Node next) {this.item item;this.next next;}}public LinkList() {//初始化头结点、this.head new Node(null, null);//初始化元素个数this.N 0;}//清空链表public void clear() {head.next null;this.N 0;}//获取链表的长度public int length() {return N;}//判断链表是否为空public boolean isEmpty() {return N 0;}//获取指定位置i出的元素public T get(int i) {//通过循环,从头结点开始往后找依次找i次就可以找到对应的元素Node n head.next;for (int index 0; index i; index) {n n.next;}return n.item;}//向链表中添加元素tpublic void insert(T t) {//找到当前最后一个结点Node n head;while (n.next ! null) {n n.next;}//创建新结点保存元素tNode newNode new Node(t, null);//让当前最后一个结点指向新结点n.next newNode;//元素的个数1N;}//向指定位置i出添加元素tpublic void insert(int i, T t) {//找到i位置前一个结点Node pre head;for (int index 0; index i - 1; index) {pre pre.next;}//找到i位置的结点Node curr pre.next;//创建新结点并且新结点需要指向原来i位置的结点Node newNode new Node(t, curr);//原来i位置的前一个节点指向新结点即可pre.next newNode;//元素的个数1N;}//删除指定位置i处的元素并返回被删除的元素public T remove(int i) {//找到i位置的前一个节点Node pre head;for (int index 0; index i - 1; i) {pre pre.next;}//要找到i位置的结点Node curr pre.next;//找到i位置的下一个结点Node nextNode curr.next;//前一个结点指向下一个结点pre.next nextNode;//元素个数-1N--;return curr.item;}//查找元素t在链表中第一次出现的位置public int indexOf(T t) {//从头结点开始依次找到每一个结点取出item和t比较如果相同就找到了Node n head;for (int i 0; n.next ! null; i) {n n.next;if (n.item.equals(t)) {return i;}}return -1;}Overridepublic IteratorT iterator() {return new LIterator();}private class LIterator implements Iterator {private Node n;public LIterator() {this.n head;}Overridepublic boolean hasNext() {return n.next ! null;}Overridepublic Object next() {n n.next;return n.item;}}//用来反转整个链表public void reverse() {//判断当前链表是否为空链表如果是空链表则结束运行如果不是则调用重载的reverse方法完成反转if (isEmpty()) {return;}reverse(head.next);}//反转指定的结点curr并把反转后的结点返回public Node reverse(Node curr) {if (curr.next null) {head.next curr;return curr;}//递归的反转当前结点curr的下一个结点返回值就是链表反转后当前结点的上一个结点Node pre reverse(curr.next);//让返回的结点的下一个结点变为当前结点currpre.next curr;//把当前结点的下一个结点变为nullcurr.next null;return curr;}
}
3.2 双向链表 双向链表也叫双向表是链表的一种它由多个结点组成每个结点都由一个数据域和两个指针域组成数据域用来存储数据其中一个指针域用来指向其后继结点另一个指针域用来指向前驱结点。链表的头结点的数据域不存储数据指向前驱结点的指针域值为null指向后继结点的指针域指向第一个真正存储数据的结点。
public class TowWayLinkListT implements IterableT {//首结点private Node head;//最后一个结点private Node last;//链表的长度private int N;//结点类private class Node {//存储数据T item;//指向上一个结点Node pre;//指向下一个结点Node next;public Node(T item, Node pre, Node next) {this.item item;this.pre pre;this.next next;}}public TowWayLinkList() {//初始化头结点和尾结点this.head new Node(null, null, null);this.last null;//初始化元素个数this.N 0;}//清空链表public void clear() {this.head.next null;this.head.pre null;this.head.item null;this.last null;this.N 0;}//获取链表长度public int length() {return N;}//判断链表是否为空public boolean isEmpty() {return N 0;}//获取第一个元素public T getFirst() {if (isEmpty()) {return null;}return head.next.item;}//获取最后一个元素public T getLast() {if (isEmpty()) {return null;}return last.item;}//插入元素tpublic void insert(T t) {if (isEmpty()) {//如果链表为空//创建新的结点Node newNode new Node(t, head, null);//让新结点称为尾结点last newNode;//让头结点指向尾结点head.next last;} else {//如果链表不为空Node oldLast last;//创建新的结点Node newNode new Node(t, oldLast, null);//让当前的尾结点指向新结点oldLast.next newNode;//让新结点称为尾结点last newNode;}//元素个数1N;}//向指定位置i处插入元素tpublic void insert(int i, T t) {//找到i位置的前一个结点Node pre head;for (int index 0; index i; index) {pre pre.next;}//找到i位置的结点Node curr pre.next;//创建新结点Node newNode new Node(t, pre, curr);//让i位置的前一个结点的下一个结点变为新结点pre.next newNode;//让i位置的前一个结点变为新结点curr.pre newNode;//元素个数1N;}//获取指定位置i处的元素public T get(int i) {Node n head.next;for (int index 0; index i; index) {n n.next;}return n.item;}//找到元素t在链表中第一次出现的位置public int indexOf(T t) {Node n head;for (int i 0; n.next ! null; i) {n n.next;if (n.next.equals(t)) {return i;}}return -1;}//删除位置i处的元素并返回该元素public T remove(int i) {//找到i位置的前一个结点Node pre head;for (int index 0; index i; index) {pre pre.next;}//找到i位置的结点Node curr pre.next;//找到i位置的下一个结点Node nextNode curr.next;//让i位置的前一个结点的下一个结点变为i位置的下一个结点pre.next nextNode;//让i位置的下一个结点的上一个结点变为i位置的前一个结点nextNode.pre pre;//元素的个数-1N--;return curr.item;}Overridepublic IteratorT iterator() {return new TIterator();}private class TIterator implements Iterator {private Node n;public TIterator() {this.n head;}Overridepublic boolean hasNext() {return n.next ! null;}Overridepublic Object next() {n n.next;return n.item;}}
}
3.3 循环链表 链表整体要形成一个圆环状。让单向链表的最后一个节点的指针指向头结点。
4 题目 4.1 反转链表 LeetCode:24 题
定义一个函数输入一个链表的头节点反转该链表并输出反转后链表的头节点。
示例
输入: 1-2-3-4-5-NULL
输出: 5-4-3-2-1-NULL
class Solution {public ListNode reverseList(ListNode head) {ListNode pre null;ListNode cur head;while(cur ! null) {ListNode tmp cur.next;cur.next pre;pre cur;cur tmp;}return pre;}
}
4.2 快慢指针 给定一个链表判断链表中是否有环。
如果链表中有某个节点可以通过连续跟踪 next 指针再次到达则链表中存在环。 为了表示给定链表中的环我们使用整数 pos 来表示链表尾连接到链表中的位置索引从 0 开始。 如果 pos 是 -1则在该链表中没有环。注意pos 不作为参数进行传递仅仅是为了标识链表的实际情况。
如果链表中存在环则返回 true 。 否则返回 false 。
示例
输入head [3,2,0,-4], pos 1
输出true
解释链表中有一个环其尾部连接到第二个节点。
public class Solution {public boolean hasCycle(ListNode head) {//快慢指针if(head null || head.next null) return false;ListNode slow head;ListNode fast head.next;while(slow ! fast){if(fast null || fast.next null) return false;slow slow.next;fast fast.next.next;}return true;}
}