건너뛰기 목록 Java
스킵 목록 Java는 요소의 하위 시퀀스에 연결되는 연결 목록 계층 구조의 도움으로 정렬된 요소 목록을 저장하는 데 사용되는 데이터 구조입니다. Skip List를 사용하면 항목 조회를 효율적으로 처리할 수 있습니다. 건너뛰기 목록은 확률적 데이터 구조입니다. 즉, 전체 목록에서 여러 요소를 건너뛰므로 건너뛰기 목록이라고 합니다. 건너뛰기 목록을 연결 목록의 확장 버전으로 사용할 수 있습니다. 연결된 목록에서 요소를 삽입, 제거하고 검색하는 방법과 유사하게 건너뛰기 목록에서도 요소를 검색하고 목록에서 요소를 제거하고 요소를 삽입할 수 있습니다. 여기에는 후속 요소의 링크 계층 구조를 유지하는 요소 집합이 포함된 기본 목록이 포함됩니다.
광고 이 카테고리에서 인기 있는 강좌 JAVA MASTERY - 전문 분야 | 78 코스 시리즈 | 15가지 모의고사무료 소프트웨어 개발 과정 시작
웹 개발, 프로그래밍 언어, 소프트웨어 테스팅 등
구문:
Skip List에는 특별한 구문이 없지만 알고리즘이 있습니다. 알고리즘을 살펴보기 전에 기본적인 Skip List 연산의 종류를 먼저 확인해야 합니다.
- 삽입 작업: Skip list에서는 특정 상황에서 특정 위치에 새 노드를 추가하는 데 사용됩니다
- 검색 작업: Skip 목록에서 특정 노드를 검색하는 데 사용됩니다
- 삭제 작업: Skip 목록에서는 특정 상황에서 노드를 삭제하는 데 사용됩니다
Java에서 건너뛰기 목록 작업
그럼 건너뛰기 목록이 실제로 알고리즘 방식으로 어떻게 작동하는지 살펴보겠습니다.
삽입 알고리즘
1단계: 목록의 각 요소가 노드로 표시되고 노드의 수준은 목록에 삽입될 때 무작위로 선택되므로 노드 수준 결정
2단계: 아래 단계에 따라 노드의 레벨이 결정됩니다
3단계: L(N) = logp/2N에 의해 결정되는 건너뛰기 목록의 수준 수에 대한 상한이 되는 최대 수준을 찾습니다. 이렇게 하면 무작위 레벨이 최대 레벨보다 높아집니다
4단계: 최상위 레벨부터 삽입이 시작되어 현재 노드의 다음 노드를 비교합니다
5단계: 다음 노드 키가 삽입된 키보다 작으면 동일한 수준으로 앞으로 나아갈 수 있습니다
6단계: 다음 노드 키가 삽입된 키보다 크면 현재 노드 I에 대한 포인터를 저장하고 한 수준 아래로 이동하여 검색을 계속해야 합니다.
검색 알고리즘
1단계: 요소 검색은 건너뛰기 목록에서 요소를 삽입할 지점을 검색하는 것과 매우 유사합니다.
2단계: 다음 노드 키가 검색 키보다 작으면 동일한 수준으로 이동할 수 있습니다
3단계: 다음 노드 키가 삽입된 키보다 크면 현재 노드 I에 대한 포인터를 저장하고 한 수준 아래로 이동하여 검색을 계속해야 합니다.
4단계: 가장 낮은 수준에서 가장 오른쪽 요소의 다음 요소에 검색 키와 동일한 키가 있으면 키를 찾은 것입니다. 그렇지 않으면 실패입니다.
삭제 알고리즘
1단계: k와 같은 요소를 삭제하려면 먼저 검색 알고리즘을 사용하여 건너뛰기 목록에서 해당 요소를 찾아야 합니다.
2단계: 검색 알고리즘을 사용하여 요소를 찾은 후에는 단일 연결 목록에서와 마찬가지로 목록에서 요소를 제거하기 위해 포인터 재배열이 수행됩니다.
3단계: 건너뛰기 목록의 가장 낮은 수준부터 시작하여 I not 요소 k 옆에 요소를 재정렬해야 합니다.
4단계: 요소 삭제 후 레벨에 요소가 없는 상황이 발생할 수 있으므로 건너뛰기 목록 레벨을 줄여 이러한 레벨을 제거해야 합니다.
Java의 건너뛰기 목록 예시
코드:
import java.util.Iterator; import java.util.Random; import java.util.NoSuchElementException; public class SkipListJava<K extends Comparable<K>, V> implements Iterable<K> { private int listsize; private double pb; protected static final Random randomGen = new Random(); protected static final double DEFAULT_PB = 0.5; private NodeKeyValue<K, V> head; public SkipListJava() { this(DEFAULT_PB); } public SkipListJava(double pb) { this.head = new NodeKeyValue<K, V>(null, null, 0); this.pb = pb; this.listsize = 0; } public V get(K key) { checkKeyValid(key); NodeKeyValue<K, V> listnode = findNode(key); if (listnode.getKey().compareTo(key) == 0) return listnode.getValue(); else return null; } public void add(K key, V value) { checkKeyValid(key); NodeKeyValue<K, V> listnode = findNode(key); if (listnode.getKey() != null && listnode.getKey().compareTo(key) == 0) { listnode.setValue(value); return; } NodeKeyValue<K, V> newlistNode = new NodeKeyValue<K, V>(key, value, listnode.getLevel()); horizontalInsertList(listnode, newlistNode); int curLevel = listnode.getLevel(); int headlistLevel = head.getLevel(); while (isBuildLevel()) { if (curLevel >= headlistLevel) { NodeKeyValue<K, V> newHeadEle = new NodeKeyValue<K, V>(null, null, headlistLevel + 1); verticalLink(newHeadEle, head); head = newHeadEle; headlistLevel = head.getLevel(); } while (listnode.getUp() == null) { listnode = listnode.getPrevious(); } listnode = listnode.getUp(); NodeKeyValue<K, V> tmp = new NodeKeyValue<K, V>(key, value, listnode.getLevel()); horizontalInsertList(listnode, tmp); verticalLink(tmp, newlistNode); newlistNode = tmp; curLevel++; } listsize++; } public void remove(K key) { checkKeyValid(key); NodeKeyValue<K, V> listnode = findNode(key); if (listnode == null || listnode.getKey().compareTo(key) != 0) throw new NoSuchElementException("Key does not exist!"); while (listnode.getDownList() != null) listnode = listnode.getDownList(); NodeKeyValue<K, V> previous = null; NodeKeyValue<K, V> next = null; for (; listnode != null; listnode = listnode.getUp()) { previous = listnode.getPrevious(); next = listnode.getNext(); if (previous != null) previous.setNext(next); if (next != null) next.setPreviousVal(previous); } while (head.getNext() == null && head.getDownList() != null) { head = head.getDownList(); head.setUp(null); } listsize--; } public boolean contains(K key) { return get(key) != null; } public int listsize() { return listsize; } public boolean empty() { return listsize == 0; } protected NodeKeyValue<K, V> findNode(K key) { NodeKeyValue<K, V> listnode = head; NodeKeyValue<K, V> next = null; NodeKeyValue<K, V> down = null; K nodeKey = null; while (true) { next = listnode.getNext(); while (next != null && lessThanEqual(next.getKey(), key)) { listnode = next; next = listnode.getNext(); } nodeKey = listnode.getKey(); if (nodeKey != null && nodeKey.compareTo(key) == 0) break; down = listnode.getDownList(); if (down != null) { listnode = down; } else { break; } } return listnode; } protected void checkKeyValid(K key) { if (key == null) throw new IllegalArgumentException("Key must be not null!"); } protected boolean lessThanEqual(K a, K b) { return a.compareTo(b) <= 0; } protected boolean isBuildLevel() { return randomGen.nextDouble() < pb; } protected void horizontalInsertList(NodeKeyValue<K, V> a, NodeKeyValue<K, V> b) { b.setPreviousVal(a); b.setNext(a.getNext()); if (a.getNext() != null) a.getNext().setPreviousVal(b); a.setNext(b); } protected void verticalLink(NodeKeyValue<K, V> a, NodeKeyValue<K, V> b) { a.setDown(b); b.setUp(a); } @Override public String toString() { StringBuilder stringbuild = new StringBuilder(); NodeKeyValue<K, V> listnode = head; while (listnode.getDownList() != null) listnode = listnode.getDownList(); while (listnode.getPrevious() != null) listnode = listnode.getPrevious(); if (listnode.getNext() != null) listnode = listnode.getNext(); while (listnode != null) { stringbuild.append(listnode.toString()).append("\n"); listnode = listnode.getNext(); } return stringbuild.toString(); } @Override public Iterator<K> iterator() { return new SkipListIterator<K, V>(head); } protected static class SkipListIterator<K extends Comparable<K>, V> implements Iterator<K> { private NodeKeyValue<K, V> listnode; public SkipListIterator(NodeKeyValue<K, V> listnode) { while (listnode.getDownList() != null) listnode = listnode.getDownList(); while (listnode.getPrevious() != null) listnode = listnode.getPrevious(); if (listnode.getNext() != null) listnode = listnode.getNext(); this.listnode = listnode; } @Override public boolean hasNext() { return this.listnode != null; } @Override public K next() { K result = listnode.getKey(); listnode = listnode.getNext(); return result; } @Override public void remove() { throw new UnsupportedOperationException(); } } protected static class NodeKeyValue<K extends Comparable<K>, V> { private K key; private V value; private int skiplevel; private NodeKeyValue<K, V> up, down, next, previous; public NodeKeyValue(K key, V value, int skiplevel) { this.key = key; this.value = value; this.skiplevel = skiplevel; } @Override public String toString() { StringBuilder stringbuild = new StringBuilder(); stringbuild.append("Node[") .append("key:"); if (this.key == null) stringbuild.append("None"); else stringbuild.append(this.key.toString()); stringbuild.append(", value:"); if (this.value == null) stringbuild.append("None"); else stringbuild.append(this.value.toString()); stringbuild.append("]"); return stringbuild.toString(); } public K getKey() { return key; } public void setKey(K key) { this.key = key; } public V getValue() { return value; } public void setValue(V value) { this.value = value; } public int getLevel() { return skiplevel; } public void setLevel(int skiplevel) { this.skiplevel = skiplevel; } public NodeKeyValue<K, V> getUp() { return up; } public void setUp(NodeKeyValue<K, V> up) { this.up = up; } public NodeKeyValue<K, V> getDownList() { return down; } public void setDown(NodeKeyValue<K, V> down) { this.down = down; } public NodeKeyValue<K, V> getNext() { return next; } public void setNext(NodeKeyValue<K, V> next) { this.next = next; } public NodeKeyValue<K, V> getPrevious() { return previous; } public void setPreviousVal(NodeKeyValue<K, V> previous) { this.previous = previous; } } public static void main(String[] args) { SkipListJava<Integer, String> skip = new SkipListJava<>(); for (int i = 20; i < 35; i++) { skip.add(i, String.valueOf(i)); } System.out.println(skip); assert skip.listsize() == 10; int count = 0; for (Integer i : skip) assert i.equals(count++); skip.remove(23); System.out.println(skip); skip.remove(25); skip.remove(33); skip.remove(30); System.out.println(skip); skip.remove(28); skip.add(25, "25"); System.out.println(skip); assert skip.listsize() == 0; assert skip.empty(); } }
출력:
스킵 목록에 추가, 스킵 목록에서 검색, 스킵 목록에서 제거를 위해 이 코드를 작성했습니다.
결론
이것으로 '스킵 리스트 자바' 주제를 마치겠습니다. 우리는 건너뛰기 목록 Java가 무엇인지, 그리고 건너뛰기 목록에서 요소 검색, 삽입 및 삭제/제거를 위한 알고리즘과 어떻게 작동하는지 살펴보았습니다. 또한 건너뛰기 목록의 모든 작업을 한 번에 수행하는 좋은 예가 있습니다. 마음속에 떠오르는 아주 다른 예나 논리를 사용해 볼 수도 있습니다. Skip list의 개념은 데이터 구조의 주요 알고리즘 중 하나인 모든 프로그래밍 언어에서 동일합니다.
위 내용은 건너뛰기 목록 Java의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

PHP는 특히 빠른 개발 및 동적 컨텐츠를 처리하는 데 웹 개발에 적합하지만 데이터 과학 및 엔터프라이즈 수준의 애플리케이션에는 적합하지 않습니다. Python과 비교할 때 PHP는 웹 개발에 더 많은 장점이 있지만 데이터 과학 분야에서는 Python만큼 좋지 않습니다. Java와 비교할 때 PHP는 엔터프라이즈 레벨 애플리케이션에서 더 나빠지지만 웹 개발에서는 더 유연합니다. JavaScript와 비교할 때 PHP는 백엔드 개발에서 더 간결하지만 프론트 엔드 개발에서는 JavaScript만큼 좋지 않습니다.

PHP와 Python은 각각 고유 한 장점이 있으며 다양한 시나리오에 적합합니다. 1.PHP는 웹 개발에 적합하며 내장 웹 서버 및 풍부한 기능 라이브러리를 제공합니다. 2. Python은 간결한 구문과 강력한 표준 라이브러리가있는 데이터 과학 및 기계 학습에 적합합니다. 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

phphassignificallyimpactedwebdevelopmentandextendsbeyondit

PHP가 많은 웹 사이트에서 선호되는 기술 스택 인 이유에는 사용 편의성, 강력한 커뮤니티 지원 및 광범위한 사용이 포함됩니다. 1) 배우고 사용하기 쉽고 초보자에게 적합합니다. 2) 거대한 개발자 커뮤니티와 풍부한 자원이 있습니다. 3) WordPress, Drupal 및 기타 플랫폼에서 널리 사용됩니다. 4) 웹 서버와 밀접하게 통합하여 개발 배포를 단순화합니다.

PHP는 웹 개발 및 컨텐츠 관리 시스템에 적합하며 Python은 데이터 과학, 기계 학습 및 자동화 스크립트에 적합합니다. 1.PHP는 빠르고 확장 가능한 웹 사이트 및 응용 프로그램을 구축하는 데 잘 작동하며 WordPress와 같은 CMS에서 일반적으로 사용됩니다. 2. Python은 Numpy 및 Tensorflow와 같은 풍부한 라이브러리를 통해 데이터 과학 및 기계 학습 분야에서 뛰어난 공연을했습니다.
