Use a linguagem C para implementar operações básicas de listas vinculadas individualmente (código completo em anexo)

Introdução:

Quer se trate de uma estrutura de armazenamento sequencial ou de uma estrutura de armazenamento encadeada, ao armazenar elementos na memória, não apenas as informações relevantes do elemento precisam ser armazenadas, mas também a relação entre o elemento e outros elementos precisa ser armazenada. aprendemos antes A estrutura física "inata" pode expressar naturalmente o relacionamento entre os elementos e não requer informações adicionais para expressar o relacionamento entre os elementos.Para estruturas de armazenamento não sequenciais, como armazenamento em cadeia, são necessários ponteiros adicionais para representar esse relacionamento.

Lista única:

Além de armazenar elementos de dados, cada nó também armazena um ponteiro para o próximo nó.

Características da lista vinculada individualmente:

Vantagens : Não requer grande espaço contínuo, capacidade fácil de alterar

Desvantagens : Sem acesso aleatório, é necessário um certo espaço para armazenar ponteiros

definição:

typedef struct LNode {
    
    
	int data;
	struct LNode* next;//指针指向下一个节点,指针的类型为节点类型;
}*LinkNode;//声明*LinkNode为结构体指针类型

Além do método acima, também podemos primeiro declarar LinkNode como um tipo de estrutura. Ao usar este tipo, basta definir a variável correspondente como um ponteiro.

As listas vinculadas individualmente são divididas em nós principais e nós não principais. Geralmente estudamos principalmente os nós principais.

Insira a descrição da imagem aqui

Operação de inicialização:

Antes de todas as operações, primeiro precisamos criar uma lista vinculada individualmente vazia e, em seguida, a primeira coisa que precisamos fazer é alocar o nó principal.

void InistLinkNode(LinkNode& L) {
    
    
	L = (LNode*)malloc(sizeof(LNode));//分配头结点
	L->next = NULL;
}

Método de inserção de cabeça:

"Método de inserção de cabeça", como o nome sugere, é inserir o elemento após o nó principal. Inserir uma vez parece não ser diferente do que costumamos falar, mas inseri-lo várias vezes após o nó principal é o "primeiro verdadeiro nó", então haverá um fenômeno em que os dados finais armazenados estarão na ordem oposta à ordem em que os inserimos?

void InsertLinkNode(LinkNode& L) {
    
    
	LNode* s;
	int x,Length;
	printf("请输入你要插入的元素个数:");
	scanf("%d", &Length);
	printf("请输入你要插入的元素:\n");
	for (int j = 0; j < Length; j++) {
    
    
		s = (LNode*)malloc(sizeof(LNode));//每插入一个元素之前,都需要给它分配节点空间
		scanf("%d", &x);
		s->data = x;
		s->next = L->next;
		L->next = s;
	}

} 

Verifique o seguinte por meio do programa:

Insira a descrição da imagem aqui

Método de inserção da cauda:

"Método de inserção de cauda", como o nome sugere, é inserir elementos no final da tabela, que é nossa inserção comum . Então, como encontramos a posição do final da tabela? Em uma tabela de sequência, podemos utilizar totalmente as características naturais de sua estrutura de armazenamento sequencial e encontrá-la por meio de subscritos. No entanto, não há como fazer isso com uma lista vinculada individualmente. Só temos duas maneiras: fazer um loop ou tentar fazer isso no final da mesa.

Então, qual método é bom?

A resposta é a segunda! A forma de percorrer o loop parece não ser problema se você inserir apenas um elemento, mas se você repetir o loop várias vezes, sem dúvida aumentará a complexidade do tempo, o que obviamente não é um bom método.

O segundo método não apresenta o problema de complexidade de tempo.只需要在表尾位置做个标记,使它永远指向表尾即可。

void TailInsertLinkNode(LinkNode& L) {
    
    
	LNode* s,*r;
	int x,Length;
	r = L;//r为表尾指针
	printf("请输入你要插入的元素个数:");
	scanf("%d", &Length);
	printf("请输入你要插入的元素:\n");
	for (int j = 0; j < Length; j++) {
    
    
		s = (LNode*)malloc(sizeof(LNode));
		scanf("%d", &x);
		s->data = x;
		r->next = s;
		r = s;//s为当前的表尾指针,将他的值赋值给r----使r永远指向表尾
	}
	printf("\n");
	r->next = NULL;
}

Exclua o i-ésimo elemento:

Como queremos excluir um elemento, primeiro precisamos 保证这个元素是非NULLe, em segundo lugar, também precisamos garantir 它前面的那个节点也是非NULL, por quê? Porque se o elemento for excluído da lista vinculada, a conexão entre o elemento subsequente e a sublista anterior só poderá ser alcançada se o nó anterior for não NULL.

void DeleteLinkNode(LinkNode& L) {
    
    
	int x, j = 0,e;
	printf("请输入你要删除的元素位序:\n");
	scanf("%d", &x);
	LNode*p = L;
	while (p != NULL && j < x - 1) {
    
    //寻找要删除元素前的元素
		p = p->next;
		j++;
	}
	if (p == NULL)
	{
    
    
		printf("不存在我们要删除的元素!");
	}
	if (p->next == NULL)//判断该要删除的节点是否为NULL
	{
    
    
		printf("不存在我们要删除的元素!");
	}
	LNode* q = p->next;//q为我们要删除的节点
	e = q->data;
	p->next = q->next;
	free(q);//需要及时的将删除了的元素空间进行释放
}

其他的基本操作都是很常规化的,这里就不单独的进行解释了,需要注意的点,我会在文章结尾部分的完整代码的注释中展出。

Inserir na posição i:

void IncreaseLinkNode(LinkNode& L) {
    
    
	printf("请输入你要插入的元素和位序:(元素和位序之间用逗号隔开)\n");
	int x, j = 0, e;
	scanf("%d,%d",&e, &x);
	LNode* s = L, * r= (LNode*)malloc(sizeof(LNode));
	while (j < x-1  && s != NULL) {
    
    
		j++;
		s = s->next;
	}
	r->data = e;
	r->next = s->next;
	s->next = r;
}

如下所示的代码顺序不能发生改变,否则会出现无法和后面的节点;

r->next = s->next;
s->next = r;

O código completo é o seguinte:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode {
    
    
	int data;
	struct LNode* next;
}*LinkNode;
//初始化
void InistLinkNode(LinkNode& L) {
    
    
	L = (LNode*)malloc(sizeof(LNode));//分配头结点
	L->next = NULL;
}
//头插法
void InsertLinkNode(LinkNode& L) {
    
    
	LNode* s;
	int x,Length;
	printf("请输入你要插入的元素个数:");
	scanf("%d", &Length);
	printf("请输入你要插入的元素:\n");
	for (int j = 0; j < Length; j++) {
    
    
		s = (LNode*)malloc(sizeof(LNode));
		scanf("%d", &x);
		s->data = x;
		s->next = L->next;
		L->next = s;
	}
} 
//尾插法
void TailInsertLinkNode(LinkNode& L) {
    
    
	LNode* s,*r;
	int x,Length;
	r = L;
	printf("请输入你要插入的元素个数:");
	scanf("%d", &Length);
	printf("请输入你要插入的元素:\n");
	for (int j = 0; j < Length; j++) {
    
    
		s = (LNode*)malloc(sizeof(LNode));
		scanf("%d", &x);
		s->data = x;
		r->next = s;
		r = s;
	}
	printf("\n");
	r->next = NULL;
}
//输出单链表
void PrintLinkNode(LinkNode& L)
{
    
    
	LNode* s=L->next;
	printf("单链表元素如下:\n");
	while (s != NULL) {
    
    
		printf("%d", s->data);
		s =s->next;
	}
	printf("\n");
}
//求线性表长度
void lengthLinkNode(LinkNode& L)
{
    
    
	LNode* s = L->next;
	int n=0;
	while (s != NULL) {
    
    
		n++;
		s = s->next;
	}
	printf("单链表长度为:%d",n);
	printf("\n");
}
//取第i个元素
void GetElemLinkNode(LinkNode& L) {
    
    
	printf("请输入你要查找的元素位序:\n");
	int i, j = 0;
	LNode* s=L;
	scanf("%d", &i);
	while (j < i && s != NULL) {
    
    
		j++;
		s = s->next;
	}
	if (s == NULL) {
    
    
		printf("不存在我们要查找的元素!");
	}
	else {
    
    
		printf("元素位序为%d的元素是%d",i, s->data);
	}
	printf("\n");
}
//删除第i个元素
void DeleteLinkNode(LinkNode& L) {
    
    
	int x, j = 0,e;
	printf("请输入你要删除的元素位序:\n");
	scanf("%d", &x);
	LNode*p = L;
	while (p != NULL && j < x - 1) {
    
    
		p = p->next;
		j++;
	}
	if (p == NULL)
	{
    
    
		printf("不存在我们要删除的元素!");
	}
	if (p->next == NULL)
	{
    
    
		printf("不存在我们要删除的元素!");
	}
	LNode* q = p->next;
	e = q->data;
	p->next = q->next;
	free(q);
}
//在第i个位置插入
void IncreaseLinkNode(LinkNode& L) {
    
    
	printf("请输入你要插入的元素和位序:(元素和位序之间用逗号隔开)\n");
	int x, j = 0, e;
	scanf("%d,%d",&e, &x);
	LNode* s = L, * r= (LNode*)malloc(sizeof(LNode));
	while (j < x-1  && s != NULL) {
    
    
		j++;
		s = s->next;
	}
	r->data = e;
	r->next = s->next;
	s->next = r;
}
//查找位序
void SearchLinkNode(LinkNode &L) {
    
    
	int x,j=1;
	LNode* p=L->next;
	printf("请输入你要查找的元素:\n");
	scanf("%d", &x);
	while (p != NULL && p->data != x) {
    
    
		p = p->next;
		j++;
	}
	if (p == NULL) {
    
    
		printf("您要查找的元素不存在!");
	}
	else {
    
    
		printf("你要查找的元素%d的位序为%d", x, j);
	}
}
int main() {
    
    
	LinkNode L;
	InistLinkNode(L);
	/*InsertLinkNode(L);*/
	TailInsertLinkNode(L);
	PrintLinkNode(L);
	lengthLinkNode(L);
	GetElemLinkNode(L);
	IncreaseLinkNode(L);
	PrintLinkNode(L);
	DeleteLinkNode(L);
	PrintLinkNode( L);
	SearchLinkNode(L);
}

Saída:

Insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/m0_64365419/article/details/127464995
Recomendado
Clasificación