C 言語を使用して、単一リンクリストの基本操作を実装します (完全なコードが添付されています)。

導入:

逐次記憶構造であっても連鎖記憶構造であっても、要素をメモリに記憶する際には、その要素の関連情報だけでなく、その要素と他の要素との関係も記憶する必要があります。以前に学習したように、「固有の」物理構造は要素間の関係を自然に表現でき、要素間の関係を表現するための追加情報は必要ありません。チェーン ストレージなどの非順次ストレージ構造の場合、この関係を表現するには追加のポインターが必要です。

単一リスト:

データ要素を格納することに加えて、各ノードは次のノードへのポインタも格納します。

単一リンクリストの特徴:

利点: 広い連続スペースが不要、容量変更が容易

短所: ランダムアクセスができないため、ポインタを格納するために一定量のスペースが必要です。

意味:

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

上記の方法以外にも、まず 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;
	}

} 

プログラムを通じて次のことを確認します。

ここに画像の説明を挿入します

テール挿入方法:

「末尾挿入法」はその名の通り、テーブルの末尾に要素を挿入する方法で、通常の挿入ですが、テーブルの末尾の位置はどうやって求めるのでしょうか?シーケンス テーブルでは、シーケンシャル ストレージ構造の自然な特性を最大限に活用し、添字を使用してそれを見つけることができます。ただし、単一リンク リストではこれを行う方法はありません。方法は 2 つしかありません。それをループするか、試してみるかです。テーブルの最後に行うには、マークを付けます。

では、どの方法が良いのでしょうか?

答えは2番目です!ループトラバーサルの方法は、要素を 1 つ挿入するだけであれば問題ないようですが、ループを複数回繰り返す場合、間違いなく時間計算量が増加し、明らかに良い方法ではありません。

2 番目の方法には時間計算量の問題はありません。只需要在表尾位置做个标记,使它永远指向表尾即可。

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;
}

i 番目の要素を削除します。

要素を削除したいので、まず保证这个元素是非NULL、次に を保証する必要があります它前面的那个节点也是非NULL。なぜでしょうか? リンクされたリストから要素が削除された場合、前のノードが 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);//需要及时的将删除了的元素空间进行释放
}

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

位置 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;

完全なコードは次のとおりです。

#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);
}

出力:

ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/m0_64365419/article/details/127464995