單向迴圈連結串列大綱

头像被封了發表於2024-04-24

單向迴圈連結串列大綱

/***********************************************************
 *
 *    file name:
 *    author   :     19870326073@163.com
 *    date     :     2024/04/23
 *    function :
 *    note     :     None
 *
 *    CopyRight (c)  2023-2024  19870326073@163.com  All Right Reseverd
 *
 * ***********************************************************/


/***********************************************************
 *
 *    函式名稱:     CircularLinkedList
 *    函式功能:
 *    函式引數:
 *
 *
 *    返回結果:
 *    注意事項:     None
 *    函式作者:     19870326073@163.com
 *    建立日期:     2024/04/23
 *    修改歷史:
 *    函式版本:     V1.0
 * ***********************************************************/

// 指的是單向迴圈連結串列中的結點有效資料型別,使用者可以根據需要進行修改
typedef int DataType_t;
// 構造單向迴圈連結串列的結點,連結串列中所有結點的資料型別應該是相同的
typedef struct CircularLinkedList
{
    DataType_t data;         // 結點的資料域
    struct CircularLinkedList *next; // 結點的指標域
} CircLList_t;

// 建立一個空單向迴圈連結串列,空連結串列應該有一個頭結點,對連結串列進行初始化
CircLList_t *CircLList_Create(void)
{
    // 1.建立一個頭結點並對頭結點申請記憶體
    CircLList_t *Head = (CircLList_t *)calloc(1, sizeof(CircLList_t));
    if (NULL == Head)
    {
        perror("Calloc memory for Head is Failed");
        exit(-1);
    }

    // 2.對頭結點進行初始化,頭結點是不儲存資料域,指標域指向自身,體現“迴圈”思想
    Head->next = Head;

    // 3.把頭結點的地址返回即可
    return Head;
}

// 建立新的結點,並對新結點進行初始化(資料域+指標域)
CircLList_t *CircLList_NewNode(DataType_t data)
{
    // 1.建立一個新結點並對新結點申請記憶體
    CircLList_t *New = (CircLList_t *)calloc(1, sizeof(CircLList_t));
    if (NULL == New)
    {
        perror("Calloc memory for NewNode is Failed");
        return NULL;
    }

    // 2.對新結點的資料域和指標域進行初始化
    New->data = data;
    New->next = NULL;

    return New;
}

// 在頭部進行插入操作
bool CircLList_HeadInsert(CircLList_t *Head, DataType_t data)
{
    CircLList_t *Phead = Head;
    // 1.建立新的結點,並對新結點進行初始化
    CircLList_t *New = CircLList_NewNode(data);
    if (NULL == New)
    {
        printf("can not insert new node\n");
        return false;
    }
    // 2.判斷連結串列是否為空,如果為空,則把新結點作為首結點,,體現“迴圈”。
    if (Head->next == Head)
    {
        New->next = New;
        Head->next = New;
        return true;
    }
    // 3.如果連結串列為非空,則需要對連結串列尾結點next指標域進行處理,指向首結點。
    while (Phead->next)
    {
        Phead = Phead->next;

        if (Phead->next == Head->next)
        {
            break;
        }
    }

    Phead->next = New;      // 尾結點的next指標指向新的首結點
    New->next = Head->next; // 新結點的next指標指向原本的首結點
    Head->next = New;
    return true;
}
// 尾部插入
bool CircLList_TailInsert(CircLList_t *Head, DataType_t data)
{
    CircLList_t *Phead = Head;

    // 1.建立新的結點,並對新結點進行初始化
    CircLList_t *New = CircLList_NewNode(data);
    if (NULL == New)
    {
        printf("can not insert new node\n");
        return false;
    }

    // 2.判斷連結串列是否為空,如果為空,則把新結點作為首結點,,體現“迴圈”。
    if (Head->next == Head)
    {
        New->next = New;
        Head->next = New;
        return true;
    }

    // 3.如果連結串列為非空,則需要對連結串列尾結點next指標域進行處理,指向首結點。
    while (Phead->next) // 移動到最後一個有效節點
    {
        Phead = Phead->next;

        if (Phead->next == Head->next)
        {
            break;
        }
    }
    Phead->next = New; // 3.進行插入操作
    New->next = NULL;
    return true;
}

/*******************************************************************
 *
 *	函式名稱:	CircLList_DestInsert
 *	函式功能:   在指定值位置處,插入指定的資料data
 * 	函式引數:
 *  				CircLList_t *Head: 需要操作的連結串列頭節點
 *  				DataType_t dest: 插入位置的值
 *  				DataType_t data: 需要插入的指定的資料
 *   返回結果:   true or false
 * 	注意事項:   None
 * 	函式作者:   19870326073@163.com
 *	建立日期:   2024/04/23
 *	修改歷史:
 *	函式版本:	V1.0
 * *****************************************************************/
bool CircLList_DestInsert(CircLList_t *Head, DataType_t dest, DataType_t data)
{
    // 1.建立新的結點,並對新結點進行初始化
    CircLList_t *New = CircLList_NewNode(data);
    if (NULL == New)
    {
        printf("can not insert new node\n");
        return false;
    }
    CircLList_t *tmp = Head;
    while (tmp->data != dest && tmp->next != NULL) // 2.移動到指定位置節點
    {
        tmp = tmp->next;
    }
    if (NULL == tmp->next)
    {
        if (tmp->data == dest)
        {
            New->next = NULL; // 3.如果指定目標值在末尾,且dest正好也在末尾,
            tmp->next = New->next;
            return true;
        }
        else
        {
            printf("There is no dest\n"); // 4.如果未找到指定目標值,則返回
            return false;
        }
    }
    New->next = tmp->next; // 5.如果指定目標值在中間,則進行插入操作。
    tmp->next = New->next;
    return true;
}
// 頭刪
bool CircLList_HeadDel(CircLList_t *Head, DataType_t data)
{
    // 對單向迴圈連結串列的頭結點的地址進行備份
    CircLList_t *Phead = Head;

    // 1.對單向迴圈連結串列的首結點的地址進行備份
    CircLList_t *Temp = Head->next;

    // 2.判斷連結串列是否為空,如果為空,則退出
    if (Head->next = Head)
    {
        printf("linkedlist is Empty\n");
        return false;
    }
    // 3。判斷連結串列中是否只有首結點
    if (Head->next = Head->next->next)
    {
        Temp->next = NULL;
        Head->next = Head;
        free(Temp);
        return true;
    }

    // 4.如果連結串列非空的,則需要對尾結點的next指標進行處理,指向新的首結點
    while (Phead->next) // 移動到最後一個有效節
    {
        Phead = Phead->next;
        if (Phead->next == Head->next)
        {
            break;
        }
    }

    Phead->next = Head->next->next; // 讓尾結點的next指標指向新的首結點

    Head->next = Phead->next; // 更新首結點,讓頭結點的next指標指向新的首結點

    Temp->next = NULL; // 舊的首結點的next指標指向NULL,從連結串列中斷開

    free(Temp); // 釋放待刪除結點的記憶體

    return true;
}
// 尾刪(一般情況下用不上)
bool CircLList_TailDel(CircLList_t *Head, DataType_t data)
{
    // 對單向迴圈連結串列的頭結點的地址進行備份
    CircLList_t *Phead = Head;

    // 1.對單向迴圈連結串列的首結點的地址進行備份
    CircLList_t *Temp = Head->next;

    // 2.判斷連結串列是否為空,如果為空,則退出
    if (Head->next = Head)
    {
        printf("linkedlist is Empty\n");
        return false;
    }
    // 3。判斷連結串列中是否只有首結點
    if (Head->next = Head->next->next)
    {
        Temp->next = NULL;
        Head->next = Head;
        free(Temp);
        return true;
    }

    // 4.如果連結串列非空的,則需要對尾結點的next指標進行處理,指向新的首結點
    while (Phead->next) // 移動到最後一個有效節
    {
        Phead = Phead->next;
        if (Phead->next == Head->next)
        {
            break;
        }
    }
    
    Phead->next = Head->next->next; // 讓尾結點的next指標指向新的首結點

    Head->next = Phead->next; // 更新首結點,讓頭結點的next指標指向新的首

    Temp->next = NULL; // 舊的首結點的next指標指向NULL,從連結串列中斷開

    free(Temp); // 釋放待刪除結點的記憶體

    return true;
}


/*******************************************************************
 *
 *	函式名稱:	CircLList_DestDel
 *	函式功能:   在指定值位置處,刪除指定的資料
 * 	函式引數:	
 *  				
 *  返回結果:   true or false
 * 	注意事項:   None
 * 	函式作者:   19870326073@163.com
 *	建立日期:   2024/04/24
 *	修改歷史:
 *	函式版本:	V1.0
 * *****************************************************************/

bool CircLList_DestDel(CircLList_t *Head, DataType_t destval)
{
	CircLList_t *tmpFormer;
	CircLList_t *tmp = Head->next;
	if (Head->next == Head) // 判斷當前連結串列是否為空,為空則直接退出
	{
		printf("current linkeflist is empty!\n");
		return false;
	}
	while (tmp->data != destval && tmp->next != Head->next) 
	{
		tmpFormer = tmp;
		tmp = tmp->next;
	}
	if (tmp->data == destval)
	{
		tmpFormer->next = tmp->next;
		tmp->next = NULL;
		free(tmp);
		return true;
	}
	else
	{
		printf("The is no destival\n");
		return false;
    }
}

相關文章