ホームページ:
まだまだ未知の部分が探索を待っている_データ構造、C言語の難しさ、小規模プロジェクト - CSDNブログ
トピック列:
目次
I.はじめに
データ構造を初めて学習する人は、最も基本的で単純な例を上手に書くようにしてください。書くたびに構造の理解が深まり、より難しい知識のための強固な基礎が築かれます。未来。他人のコードをやみくもにコピーしてはならず、最終的には自分で書かなければなりません。
2. タイトル
この質問では、指定された単一リンク リストを逆にする関数の実装が必要です。
関数インターフェースの定義:
List Reverse( List L );
構造
List
は次のように定義されます。typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */ }; typedef PtrToNode List; /* 定义单链表类型 */
L
単一リンク リストを指定すると、関数はReverse
反転リンク リストを返す必要があります。審判テスト手順の例:
#include <stdio.h> #include <stdlib.h> typedef int ElementType; typedef struct Node *PtrToNode; struct Node { ElementType Data; PtrToNode Next; }; typedef PtrToNode List; List Read(); /* 细节在此不表 */ void Print( List L ); /* 细节在此不表 */ List Reverse( List L ); int main() { List L1, L2; L1 = Read(); L2 = Reverse(L1); Print(L1); Print(L2); return 0; } /* 你的代码将被嵌在这里 */
5 1 3 4 5 2
出力サンプル:
1 2 5 4 3 1
コード長制限
16KB
制限時間
400ミリ秒
メモリ制限
64MB
3. 理解 + コード
1. 理解する
この質問を見ると、以前に学んだ文字列の反転と非常によく似ているかのように、突然非常に親しみのあるものに感じるかもしれません。
文字列の反転には多くのアイデアがあります。
1. 非再帰: 2 つの変数を使用するだけです。1 つの変数 left は文字列の最初の文字を指し、もう 1 つの変数 right は文字列の最後の文字を指し、それらを交換して終了記号を決定します。(キーコードは以下の通りです)
while(left<right) { //交换 }
2. 再帰、再帰の特性に応じて逆順序を実現
#include<stdio.h> int my_strlen(char* arr) { if (*arr != '\0') return 1 + my_strlen(arr + 1); else return 0; } char* rev(char* arr) { char tmp = *arr; int len = my_strlen(arr); *arr = *(arr + len - 1); *(arr + len - 1) = '\0'; if (my_strlen(arr+1) >=2) rev(arr + 1); *(arr + len - 1) = tmp; } int main() { char arr[] = "abcdef"; rev(arr); printf("%s", arr); return 0; }
質問: そういえば、単一リンクリストの逆の順序もこのように使用できますか?
回答: 1. 最初のアイデアを使用する場合、最後のノードへのポインタをどのように前方に移動しますか? これには、最後のノードのみを必要とする前のノードのアドレスを見つけるループが必要ですが、これはさらに面倒です。2. 2番目のアイデアを使う場合は、紙に書くだけです。使える気がします。ここで皆さんに考えてもらいたい小さな質問があります(上記の再帰的な書き方をベースに真似して、使えるかどうかを確認してください) )達成する)。
2.分析
文字列の反転で使用されるアイデアに加えて、リンク リストの特性に基づいてこの単一リンク リストの反転を完了する方法はありますか?
リンクリストを作成する際に、先頭挿入法と末尾挿入法の2つの方法を紹介しましたが、この2つの方法にはどのような特徴があるのでしょうか。まだ覚えていますか?(覚えていないリンクは以下の通りです。)データ構造---配列表---連鎖記憶構造1(先頭ノードなし)_まだまだ未知のブログが探索を待っている - CSDNブログ
ヘッド補間とテール補間の最も重要な特徴は、データの格納順序と作成後の入力データの順序です。先頭補間方式は、格納順序が入力データの順序と逆になる方式であり、末尾補間方式は、格納順序が入力データの順序と同じになる方式である。
したがって、ヘッド補間の考え方に従って、単一リンクリストのデータを1つずつ順番に読み取り、ヘッド補間方法を使用して新しいリンクリストを作成して保存できますか? 答えは「はい」です。さらに、この方法は前のアイデアよりも単純であり、リンクされたリストのいくつかの特性をよりよく具体化しています。
//ヘッド挿入方法は、前回の記事でも説明した、ヘッドが空かどうかの判定を必要としません。
3.コード
List Reverse( List L )
{
List p=L,head=NULL,q;//创建一个头指针
//头插法不需要对head是否为空进行判断,再之前的文章中也讲解过
while(p!=NULL)
{
q=(List)malloc(sizeof(struct Node));
q->Next=NULL;
q->Data=p->Data;
q->Next=head;
head=q;
p=p->Next;
}
if(L!=NULL)
L->Next=NULL;
return head;
}
ご協力ありがとうございました!