コンテンツ
単一リンクリストの紹介
単一リンクリストノード:データフィールド+ポインタフィールド(次のノードを指す)
ノード表現:
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode;
単一リンクリストのヘッドポインタ:常に線形リストの最初のノードを指し、NULLを指すノードはありません
線形テーブルチェーンタイプのストレージ特性:線形テーブルのデータ要素を格納するための任意のストレージユニットのグループです(物理アドレスは連続的または不連続的です)。
線形リストチェーンの論理的特性:データ要素間の関係は、ヘッドポインターとノード内のポインターによって示されます。
要約:
単一リンクリストは、ヘッドポインタを介して最初のノードを見つけることができ、最初のノードは、そのポインタフィールドを介して次のノードを見つけることができます。
単一リンクリストの基本操作とグラフィック分析
1.新しいノードを作成します
LNode * NewNode(EleType data)
{
LNode* newNode = (LNode*)malloc(sizeof(LNode));//创建新结点
//初始化结点
newNode->data = data;
newNode->next = NULL;
return newNode;//返回新结点指针
}
2.ヘッド挿入方式は、単一リンクリストにノードを挿入します
リンクリストが空の場合:
リンクリストが空でない場合
void LinkListPushFront(LinkList** pphead, EleType data)
{
LNode* newNode = NewNode(data);
if (*pphead == NULL)//如果链表为空,将头指针指向新结点
{
*pphead = newNode;
}
else
{
newNode->next = *pphead;//新结点的指针域指向头结点
*pphead = newNode;//头指针指向新结点
}
}
3.テール挿入方式は、単一リンクリストにノードを挿入します
リンクリストが空の場合:
リンクリストが空でない場合
void LinkListPushBack(LinkList** pphead, EleType data)
{
LinkList* tail = *pphead;
LNode* newNode = NewNode(data);
if (*pphead == NULL)//链表为空,直接将头指针指向该节点
{
*pphead = newNode;
return;
}
else
{
while (tail->next != NULL)//找到最后一个节点
{
tail = tail->next;
}
}
tail->next = newNode;//将最后一个节点和新节点连接
}
4.単一リンクリストノードを削除するヘッド削除方法
リンクリストが空の場合、削除されません。
リンクリストに複数の要素がある場合:
void LinkListPopFront(LinkList **pphead)
{
if (NULL == *pphead)//检查链表是否为空链表
{
perror("NULL\n");
return;
}
else
{
LinkList *temp = *pphead;
*pphead = (*pphead)->next;//头指针指向第二个结点
free(temp);//释放第一个结点空间
}
}
5.テール削除方法は、単一リンクリストノードを削除します
リンクリストが空の場合、削除されません。
リンクリストに要素が1つしかない場合、ノードは解放され、ヘッドポインタはnullを指します。
リンクリストに複数のノードがある場合:
void LinkListPopBack(LinkList **pphead)
{
if (NULL == *pphead)//空
{
perror("链表为空\n");
return;
}
else if ((*pphead)->next == NULL)//一个节点,直接删除
{
free(*pphead);
*pphead =NULL;
}
else
{
LinkList *tail = *pphead;
LinkList *pre = NULL;//保存倒数第二个结点的地址
while (tail->next !=NULL)//寻找尾结点
{
pre = tail;
tail = tail->next;
}
free(tail);//释放删除的结点
pre->next = NULL;
}
}
6.単一リンクリストの長さを返します
時間計算量:O(n)
int SizeLinkList(LinkList* pphead)
{
int count = 0;//计数器
if (pphead == NULL)
{
return 0;
}
else
{
while (pphead != NULL)
{
count++;
pphead = pphead->next;
}
return count;
}
}
7.単一リンクリスト内のノードを削除します
時間計算量:O(n)
頭の削除として最初の位置を削除します
int DeletElem(LinkList** pphead, int pos)
{
if (*pphead == NULL)
{
return 0;
}
else if (pos == 1)
{
LinkListPopFront(pphead);
return 1;
}
else
{
if (pos > SizeLinkList(*pphead))//判断删除的位置是否大于链表长度
{
return 0;
}
LinkList* tail = *pphead;//遍历链表节点
LinkList* pre = NULL;//删除结点的前驱结点
while (tail->next != NULL && pos>1)
{
pre = tail;
tail = tail->next;
pos--;
}
pre->next=tail->next;//将前驱结点和tail->next连接
free(tail);
return 1;
}
}
8.ノードを見つける
時間計算量:O(n)
LNode* FindElem(LinkList* pphead, EleType data)
{
if (pphead == NULL)
{
return NULL;
}
else
{
while (pphead != NULL)
{
if(pphead->data == data)
{
return pphead;
}
pphead = pphead->next;
}
return NULL;
}
9.ノードの前に新しいノードを挿入します
時間計算量:O(n)
void LinkListInsert(LinkList** head, LNode* pos, EleType data)
{
if (pos == *head)
{
//头插
LinkListPushFront(head,data);
}
else if (pos == NULL)
{
return;
}
else
{
LNode* newNode = NewNode(data);
LNode* tail = *head;
while (tail->next != pos )//查找待插入结点的前一个结点
{
tail = tail->next;
}
tail->next = newNode;
newNode->next = pos;
}
}
まとめ:
単一リンクリストの利点:挿入および削除操作中に、削除するノード上のノードのリンクアドレスのみを変更する必要があり、要素を移動する必要がないため、挿入および削除操作が連続して行われるという欠点が改善されます。ストレージ構造は、多数の要素を移動する必要があります。
単一リンクリストのデメリット:
1.継続的なストレージ割り当てが原因でテーブルの長さを判断するのが難しいという問題は解決されていません。
2.シーケンシャルストレージ構造のランダムアクセス特性が失われます。
最後に、私はあなた方全員に願っています:あなたの研究における家族の幸せと成功。