Explicación detallada de la lista de enlaces individuales y sus operaciones básicas [C&Java]

Página de inicio personal : Hola Código.
Columna de este artículo : Estructura de datos
Si tiene alguna pregunta, corríjame y aprendamos juntos ~~

contenido

Visión de conjunto

Operación básica

Inicializar lista enlazada

crear

aumento

Eliminar

cambiar

controlar

Código

lenguaje C

Java


Visión de conjunto

Una lista enlazada es una estructura de almacenamiento de datos no consecutivos y no secuenciales en una unidad de almacenamiento físico. Consiste en una serie de nodos que se pueden generar dinámicamente en tiempo de ejecución.

La lista enlazada se puede dividir en lista enlazada simple , lista enlazada doble, lista enlazada circular , etc. Este artículo muestra principalmente el funcionamiento básico de la lista de enlaces únicos, y todos los demás pueden estudiarla por sí mismos.

Cada nodo en la lista enlazada individualmente consta de dos partes: una es el campo de datos que almacena el elemento de datos y la otra es el campo de puntero que almacena la dirección del siguiente nodo .

Generalmente, también habrá head (nodo principal), end (nodo final) y p (puntero temporal) para ayudarnos a completar algunas operaciones básicas de la lista enlazada.

En la figura anterior, N1 se denomina nodo principal, N3 es el nodo final, N1 es el nodo predecesor de N2 y N2 es el nodo sucesor de N1.

Características

  1. Longitud variable
  2. Asignación discreta de n nodos
  3. Cada nodo está conectado por un puntero.
  4. Cada nodo tiene predecesores y sucesores (el nodo principal no tiene predecesor y el nodo final no tiene sucesor)

Operación básica

Entre las operaciones sobre datos, las operaciones más comunes son la adición, eliminación, modificación, búsqueda y clasificación.

Este artículo mostrará el código de la lista enlazada individualmente en Java y C.


Inicializar lista enlazada

Cada nodo en la lista enlazada corresponde a un espacio abierto en la memoria, que se divide en dos partes : el campo de datos y el campo de puntero

En lenguaje c, malloc se usa para abrir, y en Java, se usa new space para abrir espacio.

Al inicializar, es para abrir un espacio y dar la dirección al nodo principal. Debido a que no hay otros nodos durante la inicialización, también es necesario asignar el campo del puntero a NULL.

crear

Al crear una lista vinculada, ingrese la cantidad de nodos en la lista vinculada, recórrala con un bucle for, abra cada espacio por turno y asigne valores al campo de datos y al campo de puntero de cada nodo, y use punteros para conectar cada nodo La creación de la lista enlazada se puede completar para formar una estructura de lista enlazada

aumento

Para agregar un elemento a la lista vinculada, primero debe abrir un espacio en la memoria como un nuevo nodo y asignarle un valor, encontrar el nodo predecesor de la posición que se agregará, dejar que el nodo desconecte el vínculo original, señalar el nodo agregado, y luego deje que se agregue el nodo agregado.El nodo apunta al nodo sucesor original para completar. (Si hay un nodo de cabeza, el método de inserción de cabeza es similar al método de inserción de posición; el método de inserción de cola no necesita desconectar el enlace, solo deje que el extremo apunte directamente al nuevo nodo)

 

Eliminar

Para eliminar un elemento en una lista enlazada, en primer lugar, es necesario recorrer la lista enlazada para encontrar el nodo predecesor del nodo que se eliminará y dejar que el nodo apunte directamente al sucesor del nodo eliminado, que es realizar el operación de borrado omitiendo el nodo a borrar. Finalmente, en el lenguaje C, el espacio de memoria abierto por el nodo eliminado debe liberarse a través de free() para evitar el desperdicio de espacio.

Java no usa espacio libre para liberar porque Java tiene un mecanismo de recolección de basura, que se procesará automáticamente en el tiempo de inactividad

 cambiar

La modificación de los nodos en la lista enlazada es en realidad muy simple, solo necesita encontrar la posición del nodo a modificar mediante el recorrido y luego asignar directamente el valor a modificar al nodo para sobrescribir el valor anterior.

controlar

Al atravesar la lista enlazada, primero defina un puntero temporal p para apuntar a la cabeza y luego mueva continuamente el puntero p hacia atrás (p=p->siguiente) para completar el recorrido de la lista enlazada. Encontrar cada nodo se refleja en los primeros pasos de la operación, por lo que no lo mostraré aquí. El principio no es difícil y es fácil de entender.

Recorrido se refiere a obtener cada nodo a su vez, pero no significa que recorrer sea imprimir todos los datos, después de obtener cada nodo se pueden realizar varias operaciones, no solo imprimir. Pero en este artículo, para mostrar los datos de manera más intuitiva, la operación después del recorrido está configurada para imprimir


Código

En la parte de implementación del código se realizará mediante lenguajes C y Java, el código es el siguiente:

lenguaje C

1. Archivo de encabezado

#include<stdio.h>
#include<stdlib.h>

typedef int DataType;

2. Estructura de nodos de lista enlazada

typedef struct{
    DataType data;
    struct LinkList *next;
}LinkList;

3. Inicialización

LinkList *InitList(){
	LinkList *head;
	head = (LinkList*)malloc(sizeof(LinkList));
	head->next = NULL;
	return head;
}

4. Crear

void CreateList(LinkList *head, int n){
	LinkList *end, *node;
	DataType data;
	int i;
	end = head;
	for(i = 0; i < n; i++){
		node = (LinkList*)malloc(sizeof(LinkList));
		printf("请输入结点数据:");
		scanf("%d",&data);
		node->data = data;
		node->next = NULL;
		end->next = node;
		end = node;
	}
	printf("创建成功!\n");
}

5. Aumentar

void ListInsert(LinkList *head, int n){		// n表示需要添加的结点位置
	LinkList *node, *p;
	DataType data;
	int m;
	int length = ListLength(head);
	p = head;
	m = 0;
	if(n <= (length + 1) && n >= 0){
		while(p != NULL){
			if(m == n - 1) break;
			else{
				p = p->next;
				m++;
			}
		}
		node = (LinkList*)malloc(sizeof(LinkList));
		printf("请输入要插入结点的数据:");
		scanf("%d",&data);
		node->data = data;
		node->next = p->next;
		p->next = node;
		printf("添加成功!\n");
	}
	else printf("插入位置错误,请重新输入!\n");
}

6. eliminar

void ListDelete(LinkList *head,int n){
	LinkList *q, *p;
	int m = 0;
	p = head;
	while(m < n && p != NULL){
		q = p;
		p = p->next;
		m++;
	}
	if(p != NULL){
		q->next = p->next;
		free(p);
        printf("删除成功!\n");
	}
	else printf("该结点不存在,请重新输入!\n");
}

7. Cambiar

void ListChange(LinkList *head,int n){
	LinkList *p;
	DataType data;
	int i = 0;
	p = head;
	while(i < n && p != NULL){
		p = p->next;
		i++;
	}
	if(p != NULL){
		printf("请输入您要修改的值:");
		scanf("%d",&data);
		printf("%d已成功修改为%d\n",p->data,data);
		p->data = data;
	}else{
		printf("结点不存在!\n");
	}
}

8. Comprobar

void ListTraverse(LinkList *head){
	LinkList *p = head->next;
	printf("您存储的数据为:");
	while(p != NULL){
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}

principal

main(){
	LinkList *head;
	int choice = 0;
	int n;
	head = NULL;
	while(choice != 6){
		printf("-----------链表的基本操作-----------\n");
		printf("   1.初始化                         \n");
		printf("   2.增                             \n");
		printf("   3.删                             \n");
		printf("   4.改                             \n");
		printf("   5.查                             \n");
		printf("   6.退出                           \n");
		printf("------------------------------------\n");
		printf("请输入你的选择:");
		scanf("%d",&choice);
		switch(choice){
			case 1:
				head = InitList();
				printf("初始化成功!\n");
				break;
			case 2:
				if(head == NULL) printf("未初始化,请初始化后再进行操作\n");
				else{
					printf("请输入您要增加的结点数量:");
					scanf("%d",&n);
					ListInsert(head,n);
				}
				break;
			case 3:
				if(head == NULL) printf("未初始化,请初始化后再进行操作\n");
				else{
					printf("请输入您要删除的结点:");
					scanf("%d",&n);
					ListDelete(head,n);
				}
				break;
			case 4:
				if(head == NULL) printf("未初始化,请初始化后再进行操作\n");
				else{
					printf("请输入您要修改的结点:");
					scanf("%d",&n);
					ListChange(head,n);
				}
				break;
			case 5:
				ListTraverse(head);
				break;
			case 6:
				printf("退出成功,感谢您的使用!\n");
				break;
		}
	}
}

Java

1. Nodo de lista enlazada

private class Node{
	public T data;
	public Node next;		// 指向下一个结点
	
	public Node(T t){
		this(t, null);
	}
	public Node(T t, Node next){
		this.data = t;
		this.next = next;
	}
	public void set(T t){
		this.data = t;
	}
}

2. Aumentar

public void addFirst(T t){        // 头插法
		Node node = new Node(t);
		node.next = this.head;
		this.head = node;
		this.size++;
}
public void add(T t, int index){        // 指定位置插入
    if(index < 0 || index > this.size){
        throw new IllegalArgumentException("index is error");
	}
	if(index == 0){
		addFirst(t);
		return;
	}
	Node preNode = this.head;
	for(int i = 0; i < index - 1; i++){
		preNode = preNode.next;
	}
	Node node = new Node(t);
	node.next = preNode.next;
	preNode.next = node;
	this.size++;
}
public void addLast(T t){        // 尾插法
    add(t, this.size);
}

 3. eliminar

public T remove(int index){        // 指定索引删除
	if(index < 0 || index > this.size - 1){
		throw new IllegalArgumentException("index is error");
	}
	T data = null;
	if(index == 0){
		data = head.data;
		this.head = head.next;
		this.size--;
		return data;
	}
	Node preNode = this.head;
	for(int i = 0; i < index - 1; i++){
		preNode = preNode.next;
	}
	Node p = preNode.next;
	data = p.data;
	preNode.next = p.next;
	this.size--;
    return data;
}

public void remove(T t){        // 指定内容删除
	int index = getIndex(t);
	remove(index);
}

4. Cambiar

public T set(int index, T t){
	Node p = this.head;
   	for(int i = 0; i < index; i++){
		p = p.next;
	}
	T oldData = p.data;
	p.set(t);
	return oldData;
}

5. Comprobar

public boolean contains(T t){        // 查询该元素是否存在
	Node p = this.head;
	while(p != null){
		if(p.data.equals(t)) return true;
		p = p.next;
	}
	return false;
}
public int getIndex(T t){        // 查询指定元素对应索引
	Node p = this.head;
	for(int i = 0; i < this.size; i++){
		T data = p.data;
		if(data.equals(t)) return i;
		else p = p.next;
	}
	return -1;
}

6. Travesía

public void display(){
	Node p = this.head;
	while(p != null){
		System.out.println(p.data);
		p = p.next;
	}
}

código completo
 

package LinkList;

public class LinkedList <T>{
	// 链表结点
	private class Node{
		public T data;
		public Node next;		// 指向下一个结点
		
		public Node(T t){
			this(t, null);
		}
		public Node(T t, Node next){
			this.data = t;
			this.next = next;
		}
		public void set(T t){
			this.data = t;
		}
	}
	private Node head;		// 头结点
	private int size;		// 链表元素个数
	
	public LinkedList(){
		this.head = null;
		this.size = 0;
	}
	
	// 增
	
	public void addFirst(T t){
		Node node = new Node(t);
		node.next = this.head;
		this.head = node;
		this.size++;
	}
	public void add(T t, int index){
		if(index < 0 || index > this.size){
			throw new IllegalArgumentException("index is error");
		}
		if(index == 0){
			addFirst(t);
			return;
		}
		Node preNode = this.head;
		for(int i = 0; i < index - 1; i++){
			preNode = preNode.next;
		}
		Node node = new Node(t);
		node.next = preNode.next;
		preNode.next = node;
		this.size++;
	}
	public void addLast(T t){
		add(t, this.size);
	}
	
	// 删
	public T remove(int index){
		if(index < 0 || index > this.size - 1){
			throw new IllegalArgumentException("index is error");
		}
		T data = null;
		if(index == 0){
			data = head.data;
			this.head = head.next;
			this.size--;
			return data;
		}
		Node preNode = this.head;
		for(int i = 0; i < index - 1; i++){
			preNode = preNode.next;
		}
		Node p = preNode.next;
		data = p.data;
		preNode.next = p.next;
		this.size--;
		return data;
	}
	public void remove(T t){
		int index = getIndex(t);
		remove(index);
	}
	// 修改
	
	public T set(int index, T t){
		Node p = this.head;
		for(int i = 0; i < index; i++){
			p = p.next;
		}
		T oldData = p.data;
		p.set(t);
		return oldData;
	}
	// 查
	public boolean contains(T t){
		Node p = this.head;
		while(p != null){
			if(p.data.equals(t)) return true;
			p = p.next;
		}
		return false;
	}
	public int getIndex(T t){
		Node p = this.head;
		for(int i = 0; i < this.size; i++){
			T data = p.data;
			if(data.equals(t)) return i;
			else p = p.next;
		}
		return -1;
	}
	// 遍历
	public void display(){
		Node p = this.head;
		while(p != null){
			System.out.println(p.data);
			p = p.next;
		}
	}
	public static void main(String[] args){
		LinkedList<Integer> list = new LinkedList<>();
		list.addFirst(2);
		list.add(1, 1);
		list.addLast(5);
		list.display();
		System.out.println("-------------");
		list.remove(1);
		list.display();
		System.out.println("-------------");
		list.set(1, 888);
		list.display();
		System.out.println(list.contains(88));
	}
}

Supongo que te gusta

Origin blog.csdn.net/qq_24980365/article/details/120717216
Recomendado
Clasificación