單向循環鏈表的創建/插入/刪除/輸出算法

單向循環鏈表

特點:

            1> 將單向鏈表的尾結點指針域放頭結點地址,即尾結點就是頭結點的前驅結點。
            2> 爲了高效的實現某些功能,爲單向循環鏈表設置一個尾指針較爲合適(當然設置頭指針也是可以的)。

            注:第二點提到的高效體現在:訪問尾結點直接用設置的尾指針即可;訪問頭結點,即就是設置的尾指針的後繼結點。


實現單向鏈表的創建以及輸出

#include <stdio.h>
#include <stdlib.h>
#define N 7

typedef struct node {
int data ;
struct node *next;
} SN;

SN * creatlink ( int a[] )
{
SN * tail = NULL, *p;                                                          
 //tail是所設置的尾指針, p是程序中遍歷整個鏈表的指針。
int i;

for ( i = 0; i < N; i++ ) {
p = ( SN * ) malloc ( sizeof ( SN ) );
p->data = a[i];

if ( !tail ) {                                                                
//當tail爲NULL時,表示當前結點是所創建的第一個結點。
tail->next = tail = p;
}
else {                                                                       
//直接將p結點插入在尾結點後成爲新的尾結點即可。
p->next = tail->next;
tail = tail->next = p;
}
}

return tail;
}

/*在進行單向循環鏈表的輸出時,利用do-while結構比較簡單易懂,否則需要分情況使得程序出現相同代碼*/
void printlink ( SN *tail )
{
SN * p = tail;

do {
printf ("%5d", p->next->data);
p = p->next;
} while ( p != tail ); 
}

int main ( void )
{
SN * tail;
int a[N] = { 10, 20, 30, 40, 50, 60, 70 };

//創建單向循環鏈表
tail = creatlink ( a );

//輸出單向循環鏈表
printlink ( tail );

return 0;
}

單向鏈表的刪除算法

特點:單向循環鏈表在刪除時,和以前的鏈表的刪除算法一樣,待刪結點的前驅上一定要有一個指針,需要特別注意的是:尾結點的刪除,因爲專門設置了一個尾指針,所以在刪除尾結點時,一定要記得挪尾指針。


SN * delnode ( SN * tail, int delval )

{

//單向鏈表的數據域無重複值

SN * p, * delp;


p = tail;


do {

if ( p->next->data == delval )

break;

else 

p = p->next;

} while ( p != tail );                                                                                     //循環結束


if ( p == tail && tail->next->data != delval ) {                                           //沒有找到待刪結點

printf ("Not found!\n");

}

else  {                                                                                                          //找到待刪結點 

if ( tail->neat == tail ) {                                                                 

//表明此時鏈表中僅有這一個結點且當前需要刪除它。

free ( tail );

tail = NULL;

}

else {                                                                                             

//此時鏈表中有兩個結點及其以上

delp = p->next;

p->next = delp->next;


if ( delp == tail ) {                                            

             //判斷當前所要刪除結點是不是尾結點,如果是則需要先挪尾指針,否則直接釋放刪除結點

tail = p;

}

free ( delp );

}

}


return tail;

}



單向循環鏈表的插入算法

SN * insertnode ( SN * tail, SN * s )
{
//tail即尾指針, s即插入結點
//設單向循環鏈表非空且數據域的值升序有序,使得插入後,新鏈表依然升序有序

SN * p = tail;


do {

if ( p->next->data >= s->data ) {

break;

}

else 

p = p->next;

} while ( p != tail );


if ( p == tail && tail->next->data < s->data ) {                                                          

//此時表明待插結點數據大於當前尾結點數據域值,所以插入結點將成爲新的尾結點,即需挪尾指針

tail = s;

}


//接下來只需要進行插入即可

s->next = p->next;

p->next = s;


return tail;

}


附錄:以上僅僅是本人在學習單向循環鏈中的學習與實踐。由於將刪除模塊與插入模塊分開寫,所以main函數沒有寫出來,讀者可以根據自己的理解,對main函數進行正確的添加修改。
發佈了30 篇原創文章 · 獲贊 20 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章