文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>约瑟夫环问题——使用linux内核中的双向链表实现

约瑟夫环问题——使用linux内核中的双向链表实现

时间:2010-04-10  来源:蓝天22

#ifndef __LIST_H
#define __LIST_H
 
/* This file is from Linux Kernel (include/linux/list.h)
* and modified by simply removing hardware prefetching of list items.
* Here by copyright, credits attributed to wherever they belong.
* Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu)
*/

/*
* Simple doubly linked list implementation.
*
* Some of the internal functions (“__xxx”) are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/

struct list_head {
struct list_head *next, *prev;
};

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
static inline void INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list;
    list->prev = list;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}

/**
* list_add – add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}

/**
* list_add_tail – add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}

/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}

/**
* list_del – deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (void *) 0;
entry->prev = (void *) 0;
}

/**
* list_del_init – deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}

 
/**
* list_empty – tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(struct list_head *head)
{
return head->next== head;
}

static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;

first->prev = head;
head->next = first;

last->next = at;
at->prev = last;
}

 
/**
* list_entry – get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next;!list_empty(head); \
pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); \
pos = pos->prev)

/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = head, n = pos->next;!list_empty(head) ; \
pos = n, n = pos->next)
/**
 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
 * @pos:    the &struct list_head to use as a loop cursor.
 * @n:        another &struct list_head to use as temporary storage
 * @head:    the head for your list.
 */

#define list_for_each_prev_safe(pos, n, head) \
    for (pos = head , n = pos->prev; \
     pos->prev, !list_empty(head); \
     pos = n, n = pos->prev)
主要用到这个函数,由于内核遍历链表的时候只是从头到尾,而我写的是无限循环遍历,满足条件才结束,故改为这样,同时链表是没有头结点的。
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))

/**
* list_for_each_entry_safe – iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))

#endif


上边为我自己修改过的list.h 文件最近开始接触linux内核,内核中的一个双向链表设计的非常经典。想着能不能拿来用用呢?就自己琢磨着改了一部分,刚好找了格比较典型的约瑟夫环问题,实现代码如下:
josephs.c

/*
 * Copyright (c) 2009-~Gejuan Zhao
 *
 * This source code is released for free distribution under the terms of the
 * GNU General Public License
 *
 * Author: Gejuan zhao<[email protected]>
 * Created Time: Wed 31 Mar 2010 09:39:35 PM EDT
 * File Name: list.c
 *
 * Description:
 */

#include <stdio.h>
#include <stdlib.h>
#include "list.h"
struct my_list{
    int ordinal_num;
    int passwd;
    struct list_head list;
};
int main(int args, char *argv[])
{
    struct     my_list *tmp;
    struct list_head *pos,*q;
    struct my_list *listeach, *p;
    unsigned int i,j=0;
    int n,m,k=0;
    p=(struct my_list *)malloc(sizeof(struct my_list));
    printf("please input the nember of people and begian passwd:\n");
    printf("number:\t"); scanf("%d",&n);
    printf("passwd:\t"); scanf("%d",&m);
    p->ordinal_num=1;
    printf("pleae input the passwd of people 1:\t");    scanf("%d",&p->passwd);
    INIT_LIST_HEAD(&(p->list));
    for(i=0;i<n-1;i++)
    {
        tmp=(struct my_list *)malloc(sizeof(struct my_list));
        tmp->ordinal_num=i+2;
        printf("enter passwd of people %d\t",i+2);
        scanf("%d",&tmp->passwd);
        list_add(&(tmp->list),&(p->list));
    }
    printf("\n");
    printf("traversing the list using list_for_each_safe()\n");
    list_for_each_prev_safe(pos,q,&(p->list))
    {
        if(j<m-1)
              j++;
        else

        {
            tmp=list_entry(pos,struct my_list,list);
            m=tmp->passwd;
            printf(" %d quite. ",tmp->ordinal_num);
            list_del(&tmp->list);
            k++;
            if(k>=n) break;
            j=0;
         }
    }
    printf("\n");
    return 0;
}


相关阅读 更多 +
排行榜 更多 +
百炼英雄抽卡技巧指南

百炼英雄抽卡技巧指南

休闲益智 下载
英雄没有闪滚雷旋风技能如何搭配

英雄没有闪滚雷旋风技能如何搭配

休闲益智 下载
英雄没有闪雷旋风BD构筑推荐

英雄没有闪雷旋风BD构筑推荐

休闲益智 下载