上一次修改时间:2016-06-30 10:16:45

链表

1.链表实现

/*
 * 链表:插入 O(1) 查找 O(n)
 * 线性表:插入 O(logn) 查找 O(1)
 * 链表优点:不需要预先知道数据大小;
 * 链表缺点:不能随机存取,增加了节点的指针域,空间开销大
 */
#include <stdio.h>
#include <stdlib.h>
#define Error( Str )        FatalError( Str )
#define FatalError( Str )   fprintf( stderr, "%s\n", Str ), exit( 1 )
typedef int ElementType;
#ifndef _LIST_H
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;
//List MakeEmpty(List L);
int IsEmpty(List L);
int IsLast(Position P, List L);
int Find(ElementType X, List L);
void Delete(ElementType X, List L);
Position FindPrevious(ElementType X, List L);
Position Insert(ElementType X, List L, Position P);
void DeleteList(List L);
//Position Header(List L);
//Position First(List L);
//Position Advance(Position P);
//ElementType Retrieve(Position P);
#endif /* _LIST_H */
struct Node
{
    ElementType Element;
    Position Next;
};
/*初始化*/
int InitList(List *L)
{
    *L = (List)malloc(sizeof(List));
    if(!*L)
        return 0;
    (*L)->Next = NULL;
}
/* 判断链表是否为空
 * L里为链接的头节点,当头节点里的Next为空时,整个链表为空
 */
int IsEmpty(List L)
{
    return L->Next == NULL;
}
/*
 * 判断是否是链表的最后一个元素
 */
int IsLast( Position P, List L )
{
    return P->Next == NULL;
}
        
/*
 * 判断值X是在链表中的第几个节点
 */
int Find(ElementType X, List L)
{
    Position P;
    P = L->Next;
    int key = 1;
    while(P != NULL && P->Element != X)
    {
        key++;
        P = P->Next;
    }
        
    return key;
}
/*
 * 将第key个节点的值修改为X
 */
void Edit(List L, int key, ElementType X)
{
    Position P;
     P = L;
    int i,compar=0;
    //头结点的值不能修改
    if(0 != key)
    {
        for(i=0; i<key; i++)
        {
            if(P != NULL)
            {
                P = P->Next;
                compar++;
            }
            else
                break;
        }
        if(key == compar)
            P->Element = X;
        else
            printf("修改失败,该节点不存在!\n");
    }
}
/*
 * 删除值为X的节点
 */
 void Delete(ElementType X, List L)
 {
     Position P, TmpCell;
     
     P = FindPrevious(X,L);
     if(!IsLast(P,L))
     {
         TmpCell = P->Next;
         P->Next = TmpCell->Next; 
         free(TmpCell);
     }
 }
 
 /*
  * 寻找前驱
  */
 Position FindPrevious(ElementType X, List L)
 {
     Position P;
     P = L;
     while(P->Next != NULL && P->Next->Element != X)//当P->Next为NULL时,说明已到链表的末尾
         P = P->Next;
     
     return P;
 }
 
 /*
  * 将数据X插入到位置P之后
  */
Position Insert(ElementType X, List L, Position P)
{
    Position TmpCell;
    TmpCell = malloc(sizeof(struct Node));
    if(TmpCell == NULL)
        FatalError("Out of space!!!");
    
    TmpCell->Element = X;
    TmpCell->Next = P->Next;
    P->Next = TmpCell;
    
    return TmpCell;
}
/*
 * 链表遍历
 */
void TraverseList(List L)
{
    int key = 0;
    while(L->Next != NULL)
    {
        key++;
        L = L->Next;
        printf("节点%d:%d\n", key,L->Element);
    }
}
int main()
{
    int res;
    List single_list = NULL; 
    res = InitList(&single_list);
    //头结点
    Position list_position = FindPrevious(0, single_list);
    
    if(res)
    {
        int len;
        char input[10];
        int list_val=0,key;
        
        printf("初始化成功,皮卡!\n操作说明:\n");
        printf("数据插入:insert 12,将12插入到链表的尾部,皮卡!\n");
        printf("数据删除:delete 12,将12这个节点从链表中删除,皮卡!\n");
        printf("数据修改:edit 2 13,将节点2的值修改为13,皮卡!\n");
        printf("数据查询:find 13,值为13的节点是第几个,皮卡!\n");
        printf("其它:traverse,遍历整个数组,退出:exit,皮卡!\n");
    
        //主循环
        while(1)
        {
            //参数接收
            int par_key=1,par3=0;
            while(1)
            {
                if(1 == par_key)
                    scanf("%s", &input);
                else if(2 == par_key)
                    scanf("%d", &list_val);
                else if(3 == par_key)
                    scanf("%d", &par3);
                else
                    break;
                char c=getchar();
                if(c=='\n')
                    break;
                par_key++;
            }
            
            if(strcmp(input , "insert") == 0)
            {
                //结点新增
                list_position = Insert(list_val, single_list, list_position);
                printf("插入完成,新插入的值为:%d,下面是目前的链表,皮卡!\n", list_val);
                TraverseList(single_list);
            }
            else if(strcmp(input , "find") == 0)
            {
                //结点查找
                key = Find(list_val, single_list);
                printf("该元素位于第%d个节点\n", key);
            }
            else if(strcmp(input , "delete") == 0)
            {
                //结点删除
                Delete(list_val, single_list);
                printf("节点删除完成,要删除的值为:%d,下面是目前的链表,皮卡!\n", list_val);
                TraverseList(single_list);
            }
            else if(strcmp(input, "edit") == 0)
            {
                //结节修改
                Edit(single_list, list_val, par3);
                TraverseList(single_list);
            }
            else if(strcmp(input , "traverse") == 0)
            {
                //链表遍历
                TraverseList(single_list);
            }
            else if(strcmp(input , "exit") == 0)
                break;
            
        }
    }else
        FatalError("初始化失败,皮卡!");
}

运行结果:

[root@iZ28mhfkaunZ list]# ./list
初始化成功,皮卡!
操作说明:
数据插入:insert 12,将12插入到链表的尾部,皮卡!
数据删除:delete 12,将12这个节点从链表中删除,皮卡!
数据修改:edit 2 13,将节点2的值修改为13,皮卡!
数据查询:find 13,值为13的节点是第几个,皮卡!
其它:traverse,遍历整个数组,退出:exit,皮卡!
insert 12
插入完成,新插入的值为:12,下面是目前的链表,皮卡!
节点1:12

2.链表应用

木桶排序->基数排序(基数排序时,需要从低位往高位排,否则不能得出正确结果),多项式的抽象数据类型;