单链表的操作C语言实现(转)

/*
单链表的操作C语言实现
Slyar 2009.3.23
http://www.slyar.com
*/
 
#include <stdio.h>
#include <stdlib.h>
 
/* 给 char 类型定义别名 datatype */
typedef char datatype;
 
/* 定义链表节点类型 */
typedef struct node
{
        datatype data;
        struct node *next;
}linklist;
 
/* 函数声明部分 */
linklist* CreatList();
linklist* Get(linklist*, int);
linklist* Locate(linklist*, datatype);
void PrintList(linklist*);
void InsertAfter(linklist*, datatype);
void InsertBefore(linklist*, int, datatype);
void DeleteAfter(linklist*);
void Deleter(linklist*, int);
void FreeList(linklist*);
 
int main()
{
        int pos;
        datatype value;
 
        /* 测试创建链表函数 */
        printf("请输入一串字符,以 $ 结束\n");
        linklist *head, *p;
        head = CreatList();
 
        /* 测试打印链表函数 */
        printf("\n打印链表\n");
        PrintList(head);
 
        /* 测试按序号查找函数 */
        printf("\n请输入要查找的节点序号:\n");
        scanf("%d", &pos);
        getchar();
        p = Get(head, pos);
        if(p != NULL)
        {
                printf("%c\n", p -> data);
        }
        else
        {
                printf("Can't Get This Key!\n");
        }
 
        /* 测试按值查找函数 */
        printf("\n请输入要查找的值:\n");
        scanf("%c", &value);
        p = Locate(head, value);
        if(p != NULL)
        {
                printf("%c\n", p -> data);
        }
        else
        {
                printf("Can't Get This Key!\n");
        }
 
        /* 测试插入节点函数 */
        printf("\n你想在第几个节点前插入?\n");
        scanf("%d", &pos);
        getchar();
        printf("请输入要插入的值\n");
        scanf("%c", &value);
        InsertBefore(head, pos, value);
        PrintList(head);        
 
        /* 测试删除节点函数 */
        printf("\n你想删除第几个节点?\n");
        scanf("%d", &pos);
        Deleter(head, pos);
        PrintList(head);
 
        /* 销毁链表 */
        FreeList(head);
 
        //system("pause");
        return 0;
}
 
/* 带头结点后插法创建链表函数 */
linklist* CreatList()
{
        datatype key;
        /* head 为头指针, s 为新节点, r 为尾指针 */
        linklist *head, *s, *r;
        head = (linklist*) malloc(sizeof(linklist));
        r = head;
        key = getchar();
        /* 遇到 $ 就停止创建 */
        while(key != '$')
        {
                s = (linklist*) malloc(sizeof(linklist));
                s -> data = key;
                /* 新节点插入表尾 */
                r -> next = s;
                /* 尾指针指向新的表尾 */
                r = s;
                key = getchar();
        }
        r -> next = NULL;
        /* 返回头指针 */
        return head;
}
 
/* 打印链表函数 */
void PrintList(linklist* head)
{
        linklist *p;
        p = head -> next;
        while(p != NULL)
        {
                printf("%c", p -> data);
                p = p -> next;
        }
        printf("\n");
}
 
/* 查找链表中第 i 个节点 */
linklist* Get(linklist* head, int i)
{
        /* j 为扫描计数器 */
        int j = 0;
        linklist *p;
        /* p 指向头节点 */
        p = head;
        /* 到达表尾或序号不合法就退出循环 */
        while((p -> next != NULL) && (j < i))
        {
                p = p -> next;
                j++;
        }
        if (i == j)
        {
                return p;
        }
        else
        {
                return NULL;
        }
}
 
/* 在链表中查找值 key 并返回所在节点 */
linklist* Locate(linklist* head, datatype key)
{
        linklist *p;
        /* p 指向开始结点 */
        p = head -> next;
        while(p != NULL)
        {
                if(p -> data != key)
                {
                        p = p -> next;
                }
                else
                {
                        break;
                }
        }
        return p;
}
 
/* 在节点 p 后插入 key */
void InsertAfter(linklist* p, datatype key)
{
        linklist *s;
        s = (linklist*) malloc(sizeof(linklist));
        s -> data = key;
        /* 先将 s 指向后一个节点,再将前一个节点指向 s */
        s -> next = p -> next;
        p -> next = s;
}
 
/* 将 key 插入链表第 i 个节点之前 */
void InsertBefore(linklist* head, int i, datatype key)
{
        linklist *p;
        int j = i - 1;
        /* 找到第 i-1 个节点 p */
        p = Get(head, j);
        if (p == NULL)
        {
                printf("Insert Error!\n");
        }
        else
        {
                /* 将 key 插入节点 p 之后 */
                InsertAfter(p, key);
        }
}
 
/* 删除 p 节点的后继节点 */
void DeleteAfter(linklist* p)
{
        linklist *r;
        /* r 指向要删除的节点 */
        r = p -> next;
        /* 将 p 直接与 r 下一个节点链接 */
        p -> next = r -> next;
        /* 释放节点 r */
        free(r);
}
 
/* 删除链表的第 i 个节点 */
void Deleter(linklist* head, int i)
{
        linklist *p;
        int j = i - 1;
        /* 找到第 i-1 个节点 p */
        p = Get(head, j);
        if ((p != NULL) && (p -> next != NULL))
        {
                /* 删除 p 的后继节点 */
                DeleteAfter(p);
        }
        else
        {
                printf("Delete Error!\n");
        }
}
 
/* 递归释放单链表 */
void FreeList(linklist* p)
{
        if (p -> next != NULL)
        {
                FreeList(p -> next);
        }
        free(p);
}
原文地址:https://www.cnblogs.com/zhihaowang/p/10128687.html