1. 단일 연결 리스트의 특징
연결된 목록은 노드를 저장 단위로 사용하며 이러한 저장 단위는 비연속적일 수 있습니다. 단일 연결 목록의 각 노드는 저장된 값 + 후속 노드의 포인터의 두 부분으로 구성되며 다음은 단일 연결 목록의 작업입니다.
위는 단일 연결 리스트의 저장 계통도를 보여주며 간단하고 이해하기 쉽습니다. 헤드는 헤드 노드입니다. 아무 데이터도 저장하지 않지만 실제로 저장된 데이터를 가리키는 첫 번째 노드 역할을 합니다. 각 노드에는 다음 노드를 가리키는 다음 참조가 있으며, 다음이 null을 가리키는 마지막 노드까지 섹션별로 기록됩니다. (웹 인용)
2. 실제 전투
class Node {
///数据域
int data;
下一个结点
Node next;
Node(int data){
this.data = data;
}
}
class LinkList {
Node head;
void addNode(Node data) {
if (head == null) {
head = data;
return;
}
Node temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = data;
}
///插入到指定位置
void insertNodeByIndex(int index, Node newNode) {
if (index < 0 || index > getLength()) {
print("插入位置不合法");
}
if (head == null) {
head = newNode;
return;
}
int len = 0;
Node temp = head;
while (temp.next != null) {
len++;
if (len == index) {
newNode.next = temp.next;
temp.next = newNode;
break;
}
temp = temp.next;
}
}
Node removeAt(int index) {
if (index < 0 || index > getLength()) {
return null;
}
if (head == null) {
return null;
}
if (index == 0) {
//删除头结点
head = head.next;
return head;
}
Node temp = head;
Node delNode;
int len = 0;
while (temp.next != null) {
len++;
if (len == index) {
delNode = temp.next;
temp.next = temp.next.next;
break;
}
temp = temp.next;
}
return delNode;
}
bool remove(Node node) {
if (node == null) {
return false;
}
if (head == null) {
return false;
}
if (node.data == head.data) {
//删除头结点
head = head.next;
return true;
}
Node temp = head;
bool isSuccess = false;
while (temp.next != null) {
if (temp.next.next == node.next) {
temp.next = node.next;
isSuccess = true;
break;
}
temp = temp.next;
}
return isSuccess;
}
int getLength() {
if (head == null) {
return 0;
}
int len = 0;
Node temp = head;
while (temp.next != null) {
temp = temp.next;
len++;
}
return len;
}
///查找元素
Node findNodeByIndex(int index) {
if (index < 0 || index > getLength()) {
return null;
}
if (head == null) {
return null;
}
Node temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp;
}
///遍历
void printLink() {
Node curNode = head;
while (curNode != null) {
print(curNode.data);
curNode = curNode.next;
}
}
}
테스트 클래스
LinkList list = new LinkList();
Node node1 = Node(1);
Node node2 = Node(2);
Node node3 = Node(3);
list.addNode(node1);
list.addNode(node2);
list.addNode(node3);
Node node4 = Node(4);
list.insertNodeByIndex(1, node4);
print("删除前:");
list.printLink();
list.remove(node4);
print("删除的元素:${list.removeAt(1).data}");
print("删除后:");
list.printLink();
print("查找元素:${list.findNodeByIndex(1).data}");
3. 연결 리스트 요약
단일 연결 리스트, 순환 연결 리스트, 이중 연결 리스트 비교
연결 리스트 구조 | 이점 | 결점 |
---|---|---|
단일 목록 | 1. 노드를 찾은 후 시퀀스 테이블보다 삽입 및 삭제 속도가 빠름 2. 사전 할당 공간이 필요하지 않으며 요소 수에 제한이 없음 | 데이터 요소 찾기가 순차 테이블보다 느림 |
순환 연결 목록 | 단일 연결 목록을 기반으로 한 추가 개선으로 순회할 때 모든 노드에서 시작할 수 있으므로 순회 유연성이 향상됩니다. | 단일 연결 목록이 요소를 찾는 속도가 느린 문제를 해결하지 못함 |
이중 연결 리스트 | 단일 연결 목록을 기반으로 더욱 개선된 검색 요소는 접두사 노드를 반대로 검색할 수 있으므로 데이터 요소 검색 속도가 어느 정도 향상됩니다. | 접두사 노드를 기록해야 하므로 추가 메모리 공간 오버헤드 추가 |
정적 연결 목록 | 삽입 및 삭제 작업 시 요소를 이동할 필요 없이 커서만 수정하면 되므로 순차 테이블 삽입 및 삭제 시 요소 이동의 단점을 개선 | 1. 시퀀스 테이블의 길이를 결정하기 어려운 문제가 해결되지 않음 2. 시퀀스 테이블의 임의 저장 기능이 손실됨. |