Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1609894
  • 博文数量: 245
  • 博客积分: 10378
  • 博客等级: 上将
  • 技术积分: 2571
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-27 08:19
文章分类

全部博文(245)

文章存档

2013年(4)

2012年(8)

2011年(13)

2010年(68)

2009年(152)

分类: C/C++

2009-04-29 11:12:04

//////////////////////////////////////////////////////////////

// lnklst.c

// definition of queue functions

#include <stdlib.h>
#include "lnklst.h"

struct basic_nod_t {
    struct basic_nod_t *next;
};

static __inline struct basic_nod_t *find_prev_node(struct basic_nod_t *head, struct basic_nod_t *nod)
{
    struct basic_nod_t *n = head;
    if(nod == NULL)
        return NULL;
    do
    {
        if(n->next == nod)
            return n;
        n = n->next;
    } while(n && (n != nod));
    return NULL;
}

void add_node_to(void **head, void *node, void *to, int before_or_after)
{
    struct basic_nod_t **h = (struct basic_nod_t**)head;
    struct basic_nod_t *n = (struct basic_nod_t*)node;
    struct basic_nod_t *tt = (struct basic_nod_t*)to;
    if(node == NULL)
        return;
    if(*h == NULL)
    {
        *h = n;
        n->next = n;
    }
    else if(before_or_after == 0)
    {
        //move the 'moved' node to the place before 'to'

        if(tt == NULL)
            tt = *h;
        if(*h == tt)
            *h = n;
        n->next = tt;
        find_prev_node(*h, tt)->next = n;
    }
    else if(before_or_after == 1)
    {
        //move the 'moved' node to the place after 'to'

        if(tt == NULL)
            tt = find_prev_node(*h,*h);
        n->next = tt->next;
        tt->next = n;
    }
}

void add_node(void **head, void *node)
{
    add_node_to(head, node, NULL, 1);
}

void del_node(void **head, void *node)
{
    struct basic_nod_t **h = (struct basic_nod_t**)head;
    struct basic_nod_t *n = (struct basic_nod_t*)node;
    if(head == NULL)
        return;
    if(*h == NULL)
        return;
    if(n == *h)
    {
        if(n == n->next)
        {
            *h = NULL;
            return;
        }
        *h = n->next;
    }
    {
        struct basic_nod_t *tmp = find_prev_node(*h, n);
        if(tmp)
            tmp->next = n->next;
    }
}

void move_node(void **head, void *moved, void *to, int before_or_after)
{
    struct basic_nod_t **h = (struct basic_nod_t**)head;
    struct basic_nod_t *m = (struct basic_nod_t*)moved;
    struct basic_nod_t *tt = (struct basic_nod_t*)to;
    if(    (h == NULL) || (*h == NULL) || (m == tt))
        return;
    del_node(head, moved);
    add_node_to(head, moved, to, before_or_after);
}

void sort_list(void **head, CMP_FUNC nodcmp)
{
    struct basic_nod_t **h = (struct basic_nod_t**)head;
    struct basic_nod_t *nod1 = *h;
    struct basic_nod_t *nod2 = nod1->next;
    int swaped = 1;
    if(nod1 == nod1->next)
        return;
    while(swaped)
    {
        swaped = 0;
        while(1)
        {
            if((*nodcmp)(nod1, nod2) > 0)
            {
                move_node(head, nod1, nod2, 1);
                nod2 = nod1->next;
                swaped = 1;
            }
            else
            {
                nod1 = nod2;
                nod2 = nod2->next;
            }
            if(nod2 == *h)
            {
                nod1 = *h;
                nod2 = nod1->next;
                break;
            }
        }
    }
}

void add_node_sorted(void **head, void *node, CMP_FUNC nodcmp)
{
    struct basic_nod_t **h = (struct basic_nod_t**)head;
    struct basic_nod_t *n = (struct basic_nod_t*)node;
    struct basic_nod_t *tmp = *h;
    if((*nodcmp)(n, *h) < 0)
    {
        add_node_to(head, node, *h, 0);
        return;
    }
    if((*nodcmp)(n, find_prev_node(*head,*h)) >= 0)
    {
        add_node(head, node);
        return;
    }
    do
    {
        if((*nodcmp)(n, tmp) < 0)
        {
            add_node_to(head, node, tmp, 0);
            break;
        }
        else
            tmp = tmp->next;
    } while(tmp && (tmp != *h));
}

int get_node_count(void **head)
{
    struct basic_nod_t **h = (struct basic_nod_t**)head;
    struct basic_nod_t *tmp = *h;
    int count = 0;
    if(h == NULL)
        return 0;
    if(*h == NULL)
        return 0;
    do {
        tmp = tmp->next;
        count++;
    } while(tmp && (tmp != *h));
    return count;
}

头文件:

//////////////////////////////////////////////////////////////

// lnklst.h

// reference of queue functions

#pragma once
#ifdef __cplusplus
extern "C" {
#endif

#ifdef _WIN32
#define INLINE __inline
#else
#define INLINE inline
#endif

void add_node_to(void **head, void *node, void *to, int before_or_after);
void move_node(void **head, void *moved, void *to, int before_or_after);
void add_node(void **head, void *node);
void del_node(void **head, void *node);
typedef int (*CMP_FUNC)(void *t1, void *t2);
void sort_list(void **head, CMP_FUNC nodcmp);
void add_node_sorted(void **head, void *node, CMP_FUNC nodcmp);
int get_node_count(void **head);

#ifdef __cplusplus
};
#endif

 
文件: 规范链表操作.zip
大小: 1KB
下载: 下载
阅读(1146) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~