データ構造リストについて話す(Javaの説明)
リスト (線形テーブル):
リスト線形テーブルは、最も基本的で、最も単純で、最も一般的に使用されるデータ構造です. 線形テーブルは、同じ型の n 個のデータ要素を持つ有限シーケンスです. データ要素間の関係 それらはすべて 1 つである- to-one対応。
その特徴は次のとおりです。
- セットには一意の「最初の要素」が必要です
- セットには一意の「最後の要素」が必要です
- 最後の要素を除くすべての要素が固有の後継者を持つ
- 最初の要素を除くすべての要素には固有の先行要素があります
ここで言う「線形」は論理的に線形なだけなので、二重連結リストや循環連結リストも
論理的に線形リストに細分されます. 線形リストは一般線形リストと制限付き線形リストに分けられます. 一般線形リストは順序表などです.リンクされたリストは自由にノードを追加および削除できますが、制限された線形テーブルにはスタックが含まれ、キューノードでの操作は制限されています
Java の List インターフェイスによって実装されるメソッド
List インターフェイスは Collection インターフェイスから実装されます. このインターフェイスでは、ユーザーはリスト内の各要素の挿入位置を正確に制御できます. ユーザーは整数インデックスを介して要素にアクセスし、リスト内の要素を検索できます. .
セットとは異なり、リストでは通常、要素を繰り返すことができます (e1.equals(e2) == true)。
List インターフェイスの使用例:
List は Yang Hui の三角形を実現します
public List<List<Integer>> generate(int numRows) {
List<Integer> row = new ArrayList<>();
List<List<Integer>> col = new ArrayList<>();
for (int i = 0; i < numRows; i++) {
row = new ArrayList<>();
for (int j = 0; j <= i; j++) {
if (j == 0 || j == i) {
row.add(1);
} else {
List<Integer> temp = col.get(i - 1);
row.add(temp.get(j - 1) + temp.get(j));
}
}
col.add(row);
}
return col;
}
ArrayListシーケンス
テーブルは、コンピュータのメモリに配列の形式で保存される線形テーブルです.
テーブルの要素は、連続したストレージユニットのグループに1つずつ保存されます.このストレージ構造はシーケンシャル構造です.
シーケンスの本質テーブルは配列です
Java の ArrayList インターフェイスは List インターフェイスから実装され、サイズ変更可能な配列は List インターフェイスを実装し、すべてのオプションのリスト操作を実装し、null を含むすべての要素を許可します。List インターフェイスの実装に加えて、このクラスは、リストを格納するために内部で使用される配列のサイズを操作するメソッドを提供します。
各 ArrayList インスタンスには容量があります。容量は、リスト内の要素を格納するために使用される配列のサイズです。これは常に少なくともリスト サイズと同じ大きさです。要素が ArrayList に追加されると、容量がいっぱいになり、その容量は自動的に大きくなります。
ArrayListの実装——
- Iterable インターフェースの模倣
package List;
//仿写真实的(java.util.Iterable)接口
public interface Iterable {
Iterator iterator();
}
- List インターフェイスの模倣
public interface List<E> extends Iterable{
boolean add(E e);
void addIndex(int index,E e);
void clean();
boolean contains(Object o);
boolean equals(Object e);
E get(int index);
int indexOf(Object o);
boolean isEmpty();
E remove(int index);
boolean remove(Object o);
E set(int index, E e);
int size();
}
- Iterator インターフェイスの模倣
package List;
//仿写真实的(java.util.Iterator)接口
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
- ArrayList イテレータを実装する
package List;
public class ArrayListIterator implements Iterator {
//对一个顺序表迭代,重要在于控制下标
private MyArrayList arrayList;
private int index;
public ArrayListIterator(MyArrayList arrayList) {
this.arrayList = arrayList;
this.index = 0;
}
public ArrayListIterator() {
}
@Override
public boolean hasNext() {
return index < arrayList.size();
}
@Override
public Object next() {
return arrayList.get(index++);
}
@Override
public void remove() {
arrayList.clean();
}
}
- ArrayList の具体的な実装
package List;
import java.util.Arrays;
//仿写真实的(java.util.ArrayList)实现类
public class MyArrayList<E> implements List{
private int[] arr;
private int size;
public MyArrayList() {
this.arr = new int[10];
this.size = 0;
}
@Override
public boolean add(Object o) {
if (!(o instanceof Integer)) {
return false;
}
if (size == arr.length) {
capacity();
}
arr[size] = (int)o;
size++;
return true;
}
@Override
public void addIndex(int index, Object o) {
if(index < 0 || index > size+1){
return;
}
if (size == arr.length) {
capacity();
}
for (int i = size; i >= index; i--) {
arr[i + 1] = arr[i];
if (i == index) {
arr[index] = (int)o;
size++;
}
}
}
private void capacity() {
int[] newArr = new int[2 * arr.length];
System.arraycopy(arr, 0, newArr, 0, arr.length);
arr = newArr;
}
@Override
public void clean() {
size = 0;
}
@Override
public boolean contains(Object o) {
for (int e : arr){
if(e == (int)o){
return true;
}
}
return false;
}
@Override
public Object get(int index) {
if(index < 0 && index > size-1){
return null;
}else{
return arr[index];
}
}
@Override
public int indexOf(Object o) {
for (int i = 0 ;i < size;i++) {
if(arr[i] == (int)o){
return i;
}
}
return -1;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public Object remove(int index) {
if(index < 0 || index > size+1){
return null;
}
int num = arr[index];
if (size - 1 - index >= 0) System.arraycopy(arr, index + 1, arr, index, size - 1 - index);
arr[size-1] = 0;
size--;
return num;
}
@Override
public boolean remove(Object o) {
int i;
boolean isFind = false;
for (i = 0; i < size; i++) {
if(arr[i] == (int)o){
isFind = true;
break;
}
}
if(isFind) {
if (size - 1 - i >= 0) System.arraycopy(arr, i + 1, arr, i, size - 1 - i);
arr[size - 1] = 0;
size--;
}
return isFind;
}
@Override
public Object set(int index, Object o) {
if(index < 0 || index > size+1){
return null;
}
arr[index] = (int)o;
return arr[index];
}
@Override
public int size() {
return size;
}
public Iterator iterator() {
return new ArrayListIterator(this);
}
@Override
public String toString() {
return "MyArrayList{" +
"arr=" + Arrays.toString(arr) +
'}';
}
}
LinkedList (リンク リスト)
リンク リストは、非順次、非順次の物理ストレージ ユニット、論理的に順次のストレージ ストレージ構造です。リンクリスト構造を使用すると、シーケンシャルテーブルが事前にデータサイズを知る必要があるという欠点を克服でき、リンクリスト構造はコンピューターのメモリ空間を最大限に活用し、柔軟なメモリ動的管理を実現できます。リンク リストには、一方向リンク リスト、双方向リンク リスト、循環リンク リストなど、さまざまな種類があります。Java のリンク リストは、参照の形式で格納されます。
Java の LinkedList インターフェースは List インターフェース、Deque インターフェース、Cloneable インターフェース、Serializable インターフェースから実装され、二重リンク リストは List および Deque インターフェースを実装します。
オプションのリスト操作をすべて実装し、すべての要素 (null を含む) を許可します。双方向リストでは、すべての操作が期待どおりに行われます。リストへのインデックス付けは、指定されたインデックスに近い方からリストをトラバースします。
連結リスト(一方向連結リスト)の簡単な実装——
- Iterable インターフェースの模倣
package MyLinkedList;
public interface Iterable {
Iterator iterator();
}
- Iterator インターフェイスの模倣
package MyLinkedList;
public interface Iterator {
boolean hasNext();
Integer next();
}
- List インターフェイスの模倣
package MyLinkedList;
public interface List extends Iterable {
void add(Integer e);
//将指定的元素追加到此列表的末尾
boolean add(int index, Integer element);
//在此列表中的指定位置插入指定的元素
void addFirst(Integer e);
//在该列表开头插入指定的元素
void addLast(Integer e);
//将指定的元素追加到此列表的末尾
void clear();
//从列表中删除所有元素
boolean contains(Object o);
//如果此列表包含指定的元素,则返回 true
Integer getFirst();
//返回此列表中的第一个元素
Integer getLast();
//返回此列表中的最后一个元素
int indexOf(Object o);
//返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1
int lastIndexOf(Object o);
//返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1
Integer remove();
//检索并删除此列表的头(第一个元素)
Integer remove(int index);
//删除该列表中指定位置的元素
boolean remove(Object o);
//从列表中删除指定元素的第一个出现(如果存在)
Integer removeFirst();
//从此列表中删除并返回第一个元素
Integer set(int index, Integer element);
//用指定的元素替换此列表中指定位置的元素
int size();
//返回此列表中的元素数
Integer removeLast();
//从此列表中删除并返回最后一个元素
}
- LinkedListIterator クラスを定義し、Iterator インターフェイスのメソッドを実装する
package MyLinkedList;
public class LinkedListIterator implements Iterator {
private SinglyLinkedList list;
private Node cur;
public LinkedListIterator(SinglyLinkedList list) {
this.list = list;
this.cur = list.head;
}
@Override
public boolean hasNext() {
return cur != null;
}
@Override
public Integer next() {
if(cur != null) {
cur = cur.next;
return cur.element;
}else{
return null;
}
}
}
- ノード データを格納する Node クラスを定義する
package MyLinkedList;
public class Node {
Integer element;
Node next;
public Node(Integer val) {
this.element = val;
}
@Override
public String toString() {
return " " + element + " ";
}
}
- SinglyLinkedList クラスを定義し、リスト インターフェースのメソッドを実装する
package MyLinkedList;
public class SinglyLinkedList implements List{
protected Node head;
private int size;
@Override
public void add(Integer e) {
Node node = new Node(e);
if(head == null){
head = node;
}else{
Node cur = head;
while (cur.next != null){
cur = cur.next;
}
cur.next = node;
}
size++;
}
@Override
public boolean add(int index, Integer element) {
if(index < 0 || index > size){
return false;
}
if(index == 0){
addFirst(element);
return true;
}
int count = 0;
Node node = new Node(element);
Node cur = head;
while (count < index-1){
cur = cur.next;
count++;
}
Node t = cur.next;
cur.next = node;
node.next = t;
size++;
return true;
}
@Override
public void addFirst(Integer e) {
Node node = new Node(e);
node.next = head;
head = node;
size++;
}
@Override
public void addLast(Integer e) {
add(e);
}
@Override
public void clear() {
size = 0;
head = null;
}
@Override
public boolean contains(Object o) {
Node cur = head;
while (cur != null){
if(o.equals(cur.element)){
return true;
}
cur = cur.next;
}
return false;
}
@Override
public Integer getFirst() {
if(head == null) {
return null;
}else{
return head.element;
}
}
@Override
public Integer getLast() {
if(head == null){
return null;
}else{
Node cur = head;
while (cur.next != null){
cur = cur.next;
}
return cur.element;
}
}
@Override
public int indexOf(Object o) {
Node cur = head;
int count = 0;
while (cur != null) {
if(o.equals(cur.element)){
return count;
}
cur = cur.next;
count++;
}
return -1;
}
@Override
public int lastIndexOf(Object o) {
int out = -1;
int count = 0;
Node cur = head;
while (cur != null){
if(o.equals(cur.element)){
out = count;
}
cur = cur.next;
count++;
}
return out;
}
@Override
public Integer remove() {
if(head == null){
return null;
}
int out = head.element;
head = head.next;
size--;
return out;
}
@Override
public Integer remove(int index) {
if(index < 0 || index > size-1){
return null;
}
if(index == 0){
return remove();
}
Node cur = head;
Node pre = null;
int count = 0;
while(count < index){
pre = cur;
cur = cur.next;
count++;
}
int out = cur.next.element;
pre.next = cur.next;
size--;
return out;
}
@Override
public boolean remove(Object o) {
Node cur = head;
Node pre = null;
int count = 0;
while(cur != null){
if(o.equals(cur.element)){
if(pre == null){
remove();
}else {
pre.next = cur.next;
}
return true;
}
pre = cur;
cur = cur.next;
}
return false;
}
@Override
public Integer removeFirst() {
return remove();
}
@Override
public Integer set(int index, Integer element) {
int count = 0;
Node cur = head;
while (cur != null){
if(count == index){
int out = cur.element;
cur.element = element;
return out;
}
count++;
cur = cur.next;
}
return null;
}
@Override
public int size() {
return size;
}
@Override
public Integer removeLast() {
Node pre = null;
Node cur = head;
while (cur.next != null){
pre = cur;
cur = cur.next;
}if(pre == null){
return null;
}
pre.next = null;
return cur.element;
}
@Override
public Iterator iterator() {
return new LinkedListIterator(this);
}
public void print(){
Node cur = head;
System.out.print("[");
while (cur != null){
System.out.print(cur);
cur = cur.next;
}
System.out.println("]");
}
}
上記は当ブログのリストの要約です. 追跡調査の深化に伴い, コンテンツは同期的に補足および変更されます. すべてのブロガーを助けることは非常に光栄です. 訂正してください.