Linux內核思想鏈表的系列循環鏈表以及求解約瑟夫問題

歡迎加入QQ:498903810 一起交流、討論知識,裏面有大佬,也有小白,天下碼農一家親,大家一起討論進步。

注:測試程序代碼和約瑟夫環問題求解不能同時運行,但是運行時需要包含頭文件和函數體

circule_link_list.h頭文件

文件:circule_link_list.h
代碼:
#ifndef _CIRCULE_LINK_LIST_H
#define _CIRCULE_LINK_LIST_H

typedef void CirculeLinkList;
typedef void CirculeLinkListNode;

typedef struct TagCirculeLinkListNode
{
    struct TagCirculeLinkListNode * next;
}TagCirculeLinkListNode;

//創建一個循環鏈表
CirculeLinkList * LinkLIst_Creat();

//銷燬一個循環鏈表
void LinkList_Destory(CirculeLinkList * list);

//清理一個循環鏈表
void LinkList_Clear(CirculeLinkList * list);

//求鏈表長度
int LinkList_Length(CirculeLinkList * list);

//插入節點
int LinkList_Insert(CirculeLinkList * list, CirculeLinkListNode * node, int pos);

//獲取鏈表節點信息
CirculeLinkListNode * LinkList_Get(CirculeLinkList * list, int pos);

//刪除節點
CirculeLinkListNode * LinkList_Delete(CirculeLinkList * list, int pos);
//add--->新增遊標概念

//刪除遊標指向的節點
CirculeLinkListNode * CirculeLinkList_Delete(CirculeLinkList * list, CirculeLinkListNode * node);

//重置遊標
CirculeLinkListNode * CirculeLinkList_Reset(CirculeLinkList * list);

//獲取遊標位置
CirculeLinkListNode * CirculeLinkList_Current(CirculeLinkList * list);

//遊標下移
CirculeLinkListNode * CirculeLinkList_Next(CirculeLinkList * list);

#endif

circule_link_list.c函數體

文件:circule_link_list.c
代碼:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "circule_link_list.h"

typedef struct TagCircleLink
{
    TagCirculeLinkListNode head;
    TagCirculeLinkListNode * vernier;//vernier遊標
    int length;
}TagCircleLink;

//創建一個循環鏈表
CirculeLinkList * LinkLIst_Creat()
{
    TagCircleLink * begin;
    begin = (TagCircleLink *)malloc(sizeof(TagCircleLink));
    if (NULL == begin)
    {
        printf("(TagCircleLink *)malloc(sizeof(TagCircleLink)) error");
        return NULL;
    }
    begin->vernier = NULL;
    begin->length = 0;
    begin->head.next = NULL;
    return (void *)begin;
}
//銷燬一個循環鏈表
void LinkList_Destory(CirculeLinkList * list)
{
    if (NULL != list)
    {
        free(list);
    }
}
//清理一個循環鏈表
void LinkList_Clear(CirculeLinkList * list)
{
    TagCircleLink * begin;
    begin = (TagCircleLink *)list;
    begin->head.next = NULL;
    begin->length = 0;
    begin->vernier = NULL;
}
//求鏈表長度
int LinkList_Length(CirculeLinkList * list)
{
    TagCircleLink * begin;
    begin = (TagCircleLink *)list;
    return begin->length;
}
//插入節點
int LinkList_Insert(CirculeLinkList * list, CirculeLinkListNode * node, int pos)
{
    if (NULL == list || NULL == node || pos < 0)
    {
        return -1;
    }
    TagCircleLink * begin = NULL;
    TagCirculeLinkListNode * insert = NULL, * tmp = NULL;

    begin = (TagCircleLink *)list;
    insert = (TagCirculeLinkListNode *)node;
    if (NULL == begin->head.next)//第一個插入的元素特殊處理
    {
        begin->head.next = insert;
        insert->next = insert;
        begin->vernier = insert;//遊標指向0號結點
        begin->length++;
        return 0;
    }

    //如果插入的是零號位置特殊處理,插入零號位置相當於插入在最後一個位置,然後把頭結點後移一位,
    if (pos > begin->length)
    {
        pos = begin->length;
    }
    if (0 == pos)
    {
        LinkList_Insert(list, node, begin->length);
        begin->head.next = insert;
        begin->vernier = insert;
        return 0;
    }

    tmp = begin->head.next;
    for (int i = 0; i < pos - 1; i++)
    {
        tmp = tmp->next;
    }
    insert->next = tmp->next;
    tmp->next = insert;
    begin->length++;
    return 0;
}
//獲取鏈表節點信息
CirculeLinkListNode * LinkList_Get(CirculeLinkList * list, int pos)
{
    if (NULL == list  || pos < 0)
    {
        return NULL;
    }
    TagCircleLink * begin = NULL;
    TagCirculeLinkListNode * tmp = NULL;
    begin = (TagCircleLink *)list;
    tmp = begin->head.next;
    for (int i = 0; i < pos; i++)
    {
        tmp = tmp->next;
    }
    return (void *)tmp;
}
//刪除節點
CirculeLinkListNode * LinkList_Delete(CirculeLinkList * list, int pos)
{
    if (NULL == list || pos < 0)
    {
        return NULL;
    }
    TagCircleLink * begin = NULL;
    TagCirculeLinkListNode * tmp = NULL, * ret = NULL;
    begin = (TagCircleLink *)list;
    tmp = begin->head.next;
    if (pos >= begin->length)
    {
        return NULL;
    }
    if (begin->vernier == (TagCirculeLinkListNode *)LinkList_Get(list, pos))//如果刪除的結點是遊標指向的位置,遊標下移
    {
        begin->vernier = begin->vernier->next;
    }
    if (begin->length == 1 && pos == 0)//如果刪除的最後一個結點
    {
        CirculeLinkListNode * ret = begin->head.next;
        begin->length--;
        begin->vernier = NULL;
        begin->head.next = NULL;
        return ret;
    }
    if (0 == pos)//如果是刪除的頭號結點特殊處理
    {
        begin->head.next = begin->head.next->next;//頭結點移到一號位置
        CirculeLinkListNode * sign = LinkList_Delete(list, begin->length - 1);//刪除最後一個元素
        if (NULL != sign)
        {
            return sign;
        }
        else
            return NULL;
    }


    for (int i = 0; i < pos - 1; i++)//刪除普通結點
    {
        tmp = tmp->next;
    }
    ret = tmp->next;
    tmp->next = tmp->next->next;
    begin->length--;
    return (void *)ret;
}

//add--->新增遊標概念
//刪除遊標指向的節點
CirculeLinkListNode * CirculeLinkList_Delete(CirculeLinkList * list, CirculeLinkListNode * node)
{
    //node是要刪除的位置
    if (NULL == list || NULL == node)
    {
        return NULL;
    }
    int i = 0;
    TagCirculeLinkListNode * del = (TagCirculeLinkListNode *)node, * tmp = NULL;
    TagCircleLink * begin = (TagCircleLink *)list;
    tmp = begin->head.next;
    for (i = 0; i <= begin->length; i++)//找到要刪除的結點的位置
    {
        if (i == begin->length)
        {
            return NULL;
        }
        if (del == tmp)
        {
            break;
        }
        tmp = tmp->next;
    }
    tmp = (TagCirculeLinkListNode *)LinkList_Delete(list, i);//移動結點
    if (tmp != NULL)
    {
        return tmp;
    }
    else
        return NULL;

}
//重置遊標
CirculeLinkListNode * CirculeLinkList_Reset(CirculeLinkList * list)
{
    if (NULL == list)
    {
        return NULL;
    }
    TagCircleLink * begin = NULL;
    begin = (TagCircleLink *)list;

    begin->vernier = begin->head.next;
    return (CirculeLinkListNode *)begin->vernier;
}
//獲取遊標位置
CirculeLinkListNode * CirculeLinkList_Current(CirculeLinkList * list)
{
    if (NULL == list)
    {
        return NULL;
    }
    TagCircleLink * begin = (TagCircleLink *)list;
    return (CirculeLinkListNode *)begin->vernier;

}
//遊標下移
CirculeLinkListNode * CirculeLinkList_Next(CirculeLinkList * list)
{
    if (NULL == list)
    {
        return NULL;
    }
    TagCircleLink * begin = (TagCircleLink *)list;
    (TagCirculeLinkListNode *)begin->vernier;
    begin->vernier = begin->vernier->next;
    return (CirculeLinkListNode *)begin->vernier;
}

Joseph_question.c約瑟夫環問題求解

文件:Joseph_question.c
代碼:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "circule_link_list.h"

typedef struct Teacher
{
    TagCirculeLinkListNode * next;
    int age;
    char name[64];
}Teacher;

int main()
{
    Teacher t1;
    Teacher t2;
    Teacher t3;
    Teacher t4;
    Teacher t5;
    Teacher t6;
    Teacher t7;
    Teacher t8;
    Teacher t9;
    t1.age = 21;
    t2.age = 22;
    t3.age = 23;
    t4.age = 24;
    t5.age = 25;
    t6.age = 26;
    t7.age = 27;
    t8.age = 28;
    t9.age = 29;

    CirculeLinkList * list;
    Teacher * tmp;
    CirculeLinkList * ret = NULL;
    //創建鏈表
    list = LinkLIst_Creat();

    //插入元素
    LinkList_Insert(list, (CirculeLinkListNode *)&t1, 0);
    LinkList_Insert(list, (CirculeLinkListNode *)&t2, 0);
    LinkList_Insert(list, (CirculeLinkListNode *)&t3, 0);
    LinkList_Insert(list, (CirculeLinkListNode *)&t4, 0);
    LinkList_Insert(list, (CirculeLinkListNode *)&t5, 0);
    LinkList_Insert(list, (CirculeLinkListNode *)&t6, 0);
    LinkList_Insert(list, (CirculeLinkListNode *)&t7, 0);
    LinkList_Insert(list, (CirculeLinkListNode *)&t8, 0);
    LinkList_Insert(list, (CirculeLinkListNode *)&t9, 0);

    //遍歷元素
    for (int i = 0; i < LinkList_Length(list); i++)
    {
        Teacher *tmp = NULL;
        ret = LinkList_Get(list, i);
        tmp = (Teacher *)ret;
        printf("age = %d\n", tmp->age);
    }

    printf("約瑟夫問題求解\n");
    for (int i = 0; i < LinkList_Length(list);)
    {
        for (int j = 0; j < 2; j++)
        {
            CirculeLinkList_Next(list);
        }
        ret = CirculeLinkList_Delete(list, CirculeLinkList_Current(list));
        if (ret != NULL)
        {
            tmp = (Teacher *)ret;
            printf("age = %d\n", tmp->age);
        }
        else
        {
            printf("error\n");
        }
    }
    system("pause");
    return 0;
}

測試程序代碼

程序測試代碼
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "circule_link_list.h"

typedef struct Teacher
{
    TagCirculeLinkListNode * next;
    int age;
    char name[64];
}Teacher;

int main()
{
    Teacher t1;
    Teacher t2;
    Teacher t3;
    Teacher t4;
    Teacher t5;
    t1.age = 21;
    t2.age = 22;
    t3.age = 23;
    t4.age = 24;
    t5.age = 25;
    CirculeLinkList * list;
    CirculeLinkList * ret = NULL;
    //創建鏈表
    list = LinkLIst_Creat();

    //插入元素
    LinkList_Insert(list, (CirculeLinkListNode *)&t1, 0);
    LinkList_Insert(list, (CirculeLinkListNode *)&t2, 1);
    LinkList_Insert(list, (CirculeLinkListNode *)&t3, 0);

    //CirculeLinkListNode * LinkList_Get(CirculeLinkList * list, int pos);
    //遍歷元素
    for (int i = 0; i < LinkList_Length(list); i++)
    {
        Teacher *tmp = NULL;
        ret = LinkList_Get(list, i);
        tmp = (Teacher *)ret;
        printf("age = %d\n", tmp->age);
    }

    ////刪除元素 --- > 測試通過
    //for (int i = 0; i < LinkList_Length(list);)
    //{
    //  ret = LinkList_Delete(list, 0);
    //  if (ret == NULL)
    //  {
    //      printf("刪除失敗!!!\n");
    //      break;
    //  }
    //  else
    //  {
    //      Teacher *tmp = NULL;
    //      tmp = (Teacher *)ret;
    //      printf("被刪除的年齡是 age = %d\n", tmp->age);
    //  }
    //}

    //測試通過
    //ret = CirculeLinkList_Delete(list, (CirculeLinkListNode *)& t1);
    //if (ret == NULL)
    //{
    //  printf("失敗!!!\n");
    //}
    //else
    //{
    //  Teacher *tmp = NULL;
    //  tmp = (Teacher *)ret;
    //  printf("年齡是 age = %d\n", tmp->age);
    //}
    ////遍歷元素
    //for (int i = 0; i < LinkList_Length(list); i++)
    //{
    //  Teacher *tmp = NULL;
    //  ret = LinkList_Get(list, i);
    //  tmp = (Teacher *)ret;
    //  printf("age = %d\n", tmp->age);
    //}

    //測試通過
    //ret = CirculeLinkList_Reset(list);
    //Teacher *tmp = NULL;
    //tmp = (Teacher *)ret;
    //printf("年齡是 age = %d\n", tmp->age);

    ret = CirculeLinkList_Next(list);
    Teacher *tmp = NULL;
    tmp = (Teacher *)ret;
    printf("年齡是 age = %d\n", tmp->age);

    /*
    //創建一個循環鏈表
    CirculeLinkList * LinkLIst_Creat();
    //銷燬一個循環鏈表
    void LinkList_Destory(CirculeLinkList * list);
    //清理一個循環鏈表
    void LinkList_Clear(CirculeLinkList * list);
    //求鏈表長度
    int LinkList_Length(CirculeLinkList * list);
    //插入節點
    int LinkList_Insert(CirculeLinkList * list, CirculeLinkListNode * node, int pos);
    //獲取鏈表節點信息
    CirculeLinkListNode * LinkList_Get(CirculeLinkList * list, int pos);
    //刪除節點
    CirculeLinkListNode * LinkList_Delete(CirculeLinkList * list, int pos);
    //add--->新增遊標概念
    //刪除遊標指向的節點
    CirculeLinkListNode * CirculeLinkList_Delete(CirculeLinkList * list, CirculeLinkListNode * node);
    //重置遊標
    CirculeLinkListNode * CirculeLinkList_Reset(CirculeLinkList * list);
    //獲取遊標位置
    CirculeLinkListNode * CirculeLinkList_Current(CirculeLinkList * list);
    //遊標下移
    CirculeLinkListNode * CirculeLinkList_Next(CirculeLinkList * list);
    */
    system("pause");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章