`
anysky131
  • 浏览: 172482 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

C语言编写的单链表(测试通过)

 
阅读更多
#ifndef List_H
#define List_H
#endif
typedef int Item;
typedef struct node * PNode;

typedef struct node
{
    Item item;
    PNode next;
} Node;

typedef PNode Position;
typedef PNode List;


/*
功能
n生空链表L
*/
List MakeEmpty(List L);

/*
功能
判定链表是否为空
 */
int IsEmpty(List L);

/*
功能
判定位置P的节点是否为尾节点
 */
int IsLast(Position P);
/*
功能
在链表L中查找数据项为X的第一个节点
 */
Position Find(Item X, List L);

/*
功能
在链表L中删除数据项为X的第一个节点
*/
void Delte(Item X, List L);

/*
功能
在链表L中查找数据项为X的第一个节点的前驱位置
 */
Position FindPrevious(Item X, List L);

/*
功能
在链表L中查找数据项为X的第一个节点的后继位置
 */
Position FindNext(Item X, List L);

/*
功能
在链表L中P位置插入数据项为X的节点
 */
void Insert(Item X, List L, Position P);

/*
功能
删除链表L初头节点外的所有节点
 */
void DelteList(List L);

/*
功能
获得链表L中头节点位置
 */
Position Header(List L);

/*
功能
获得链表L中第一个数据节点位置
 */
Position First(List L);

/*
功能
获得位置P的后继节点位置
 */
Position Advance(Position P);


/*
功能
获得P位置节点的数据项
 */
Item Retrieve(Position P);


 

list.c

#include "list.h"
#include <malloc.h>
#include <stdlib.h>

List MakeEmpty(List L)
{
    L = (PNode)malloc(sizeof(Node));
    L->item = 0;
    L->next = NULL;
    return L;
}

int IsEmpty(List L)
{
    return L->next == NULL;
}

int IsLast(Position P)
{
    return P->next == NULL;
}

Position Find(Item X, List L)
{
    Position P;
    P = L->next;
    while(P!=NULL && P->item!=X)
    {
        P = P->next;
    }

    return P;
}

void Delete(Item X, List L)
{
    Position P, temp;
    P = FindPrevious(X,L);
    if(!IsLast(P))
    {
        temp = P->next;
        P->next = temp->next;
        free(temp);
    }
}

Position FindPrevious(Item X, List L)
{
    Position P;
    P = L;
    while(P->next!=NULL && P->next->item != X)
    {
        P= P->next;
    }
    return P;
}

Position FindNext(Item X, List L)
{
    Position P;
    P = L;
    while(P!=NULL && P->item != X)
    {
        P = P->next;
    }
    return P->next;
}

void Insert(Item X, List L, Position P)
{
    Position tmp;
    tmp = malloc(sizeof(Node));
    if(tmp == NULL)
    exit(0);
    tmp->item = X;
    tmp->next = P->next;
    P->next = tmp;
    
}

void DeleteList(List L)
{
    Position P, tmp;
    P=L->next;
    L->next = NULL;
    while(P!=NULL)
    {
        tmp = P->next;
        free(P);
        P = tmp;
    }
}

Position Header(List L)
{
    return L;
}

Position Fist(List L)
{
    if(L->next != NULL)
    return L->next;
}

Position Advance(Position P)
{
    if(P!=NULL)
    return P->next;
}

Item Retrieve(Position P)
{
    if(P!=NULL)
    return P->item;
}

 

testlist.c

#include "list.h"
#include <stdlib.h>
#include <stdio.h>

int main()
{
    List list=NULL;
    Position P, currentP;
    int i, num;
    num = 10;
    list = MakeEmpty(list);
    if(IsEmpty(list)){
        printf("list is NULL \n");
    }

    P = list;
    for(i=0;i<num;i++)
    {
        Insert(i*i,list,P);
        P = Advance(P);
        printf("already insert %d \n",Retrieve(P));
    }
    
    currentP = Find(25, list);
    printf("currentP is %d \n", currentP->item);
    P = FindNext(currentP->item,list);
    printf("next of number 25 is: %d \n",Retrieve(P));

    P = FindPrevious(currentP->item,list);
    printf("preview of number 25 is: %d \n",Retrieve(P));

    Delete(currentP->item,list);

    P=list;

    for(i=0;i<num;i++)
    {
        P = Advance(P);
        printf("after delete %d \n",Retrieve(P));
    }

    DeleteList(list);
    printf("already deleted list\n");
    if(IsEmpty(list))
    printf("list is NULL\n");
}

 

测试环境Fedora 20, gcc (GCC) 4.8.3 20140624

编译命令:gcc list.c testlist.c -o output.out

 

 

以下是同一个例子,但在前一个基础上添加了一些头元素与尾元素的校验,目前只实现了新建,初使化,校验长度,在链表头与尾添加元素,删除某个元素,及清除整个链表功能

功能都已经在实际电脑上测试通过;

#include <stdlib.h>
#include <stdio.h>
 #include <malloc.h>

typedef int Item;
typedef struct SingleNode * PNode;
typedef struct SingleNode{
    Item item;
    PNode next;
} Node;

//创建一个链表中位置指针
typedef PNode Position;
//创建一个链表集合,实际也是一个指针,指向链表第一个元素的指针
typedef PNode List;

/*
创建一个链表,并初使化为一个包含0值的元素
 */
List createEmpty(List L)
{
    L = (PNode)malloc(sizeof(Node));
    L->item = 0;//创建了一个值为0的表头
    L->next = NULL;
    return L;
}

/*
x打印元素清单
 */
void
printList(List L)
{
    int i=0;
    Position P;
    P = L;
    
    while(P!=NULL)
    {
        printf("number %d of this list is: %d\n",i,P->item);
        P = P->next;
        i++;
        
    }
}

/*
插入链表新的元素
 */
void
insertElement(Item X, List L, Position P)
{
    Position tmp;
    tmp = malloc(sizeof(Node));
    if(tmp == NULL)
    exit(0);
    tmp->next = P->next;
    tmp->item = X;
    P->next = tmp;
    
}

/*
返回链表第一个元素
 */
Position
getFirst( List L)
{
    if(L->next!=NULL)
    return L->next;
}

/*
返回链表的最后一个元素
 */
Position
getLast(List L)
{
    Position P;
    P = L;
    while(P->next!=NULL)
    P = P->next;
    return P;
}


/*
在链表头部插入元素
 */
void
insertElementAtStart(Item X, List L)
{
  insertElement(X,L,L);
    
}

/*
在链表尾部插入元素
 */
void insertElementAtEnd(Item X, List L)
{
    Position  end, P;
    P = L;
    end = getLast(P);
    insertElement(X,L,end);
}

Position
getPosition(Item X,const List L)
{
    Position P;
    P = L;
    
    while(P!=NULL && P->item != X)
    {
        P=P->next;
    
    }
    
    return P;
}            



/*
获得当前元素的前一个元素
 */
Position
getPreviewElement(Item X, const List L)
{
    Position P, tmpX;
    P = L;
    if(isFirst(X,P))
    return NULL;
    
    while(P->next!=NULL && P->next->item != X)
    {
        P = P->next;
    }
    
    return P;
}


/*
获取链表当前元素的下一个元素
 */
Position
getNextElement(Item X,const  List L)
{
    Position P,tmpX;
    P = L;
    if(isLast(X,P))
    return NULL;
   
    while(P != NULL && P->item != X)
    {
        P = P->next;
    }
    return P->next;//返回当前元素的下一个元素
    }
/*
获取链表长度
 */
int
getLength(const List L)
{
    Position P;
    P = L;
    int j = 0;
    while(P != NULL)
    {
        P = P->next;
        j++;
    }
    return j;
}


/*
判断是否是最后一个节点
*/
int
isLast(Item X,const List L)
{
    Position P;
    P = L;
    while(P!=NULL && P->item != X)
    P = P->next;
    return P->next == NULL;
}

/*
判断是否是第一个元素
 */
int
isFirst(Item X, const List L)
{
    return L!=NULL && (L->item == X);
}



/*
判断当前链表是否为空
 */

int
isEmpty(List L)
{
    return L->next == NULL;
}
/*
获取当前元素的下一个节点指针
 */
Position
advance(Position P)
{
    if(P != NULL)
    return P->next;
}
             
/*
获取当前元素的元素值
 */
Item
retrieve(Position P)
{
    if(P!=NULL)
    return P->item;
}


/*
删除指定值的元素
**/
void deleteElement(Item X, List L)
{
    Position tmp,P;
    if(isFirst(X,L))
    {
        P = L;
        tmp = P;
        L->next = tmp->next->next;//因测试前执行了P2=P2->next去掉过表头
        free(tmp);
    }
    else
    {
        P = getPreviewElement(X, L);
        tmp = P->next;
        P->next = tmp->next;
        free(tmp);
    }
    
}

/*
删除除表头外所有元素
 */
void deleteList(List L)
{
    Position P, tmp;
    P = L;
    while(P!=NULL)
    {
        printf("p is: %d\n",P->item);
        tmp = P->next;
        free(P);
        P = tmp;
    }
    L->next = NULL;
}

/*
打印测试
 */
void
printTest(Item X, List list)
{
    printList(list);
    printf("the length of this list is: %d\n", getLength(list));
    Position previewE = getPreviewElement(X, list);
    if(previewE == NULL)
    printf("item %d is the first item, no preview element exist!\n", X);
    else
    printf("the previews of item %d is: %d\n", X, previewE->item);
    Position nextE = getNextElement(X, list);
    if(nextE == NULL)
    printf("item %d is the last item, no next element exist!\n",X);
    else
    printf("the next of item %d is: %d\n", X, nextE->item);

}

int
main()
{
    List list = NULL;
    Position P,P1,P2,P3;
    int i, num;
    Item item = 16;
    num = 10;
    list = createEmpty(list);
    if(isEmpty(list))

    P = list;
    //创建及打印某元素的前置与后继元素及长度
    for(i=0;i<num;i++)
    {
        insertElement(i*i, list, P);
        P = advance(P);
    }
    printf("创建链表完成后打印\n");
    P1 = list->next;//跳过表头
    printTest(item, P1);

    //链表头插入元素及打印元素的前置与后继元素及长度
    Item startItem = 100;
    P2 = list;
    insertElementAtStart(startItem,P2);
    printf("头部插入元素newItem:%d 后的打印\n",startItem);
    P2 = P2->next;//跳过表头
    printTest(startItem,P2);

    //链表尾插入元素及打印元素的前置与后继元素及长度
    Item endItem = 110;
    insertElementAtEnd(endItem,P2);
    printf("尾部插入元素newItem:%d 后的打印\n",endItem);
    printTest(endItem,P2);

    //删除元素及打印元素的前置与后继元素及长度
    Item deleteItem = 16;//测试过头元素100, 尾元素100,均删除正常
    deleteElement(deleteItem,P2);
    printf("删除元素 %d 后的打印\n",deleteItem);
    printTest(9,P2);

    //删除链表除表头外所有元素,删除后加上表头链表长度为1
    deleteList(P2);
    printf("删除所有元素后打印");
    printList(P2);
    printf("删除后链表长度为:%d\n",getLength(P2));
    
}

 

 

分享到:
评论

相关推荐

    学生管理系统(C语言)(单链表)

    1、实现软件:Dev-C++ 2、详细的测试页面可见我《资源》专栏下的《C语言系统资源测试》。 3、适合新手下载学习。 4、基于C语言的单链表实现。 5、代码共255行 6、注释多,排版有序

    c语言难点分析整理,C语言

    60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66...

    C语言课程设计

    ⑵ 编写集合元素输入并插入到单链表中的函数INSERT_SET,保证所输入的集合中的元素是唯一且以非递减方式存储在单链表中; ⑶ 编写集合元素输出函数,对建立的集合链表按非递增方式输出; ⑷ 编写求集合A、B的交C=A∩...

    高级C语言详解

    60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66...

    史上最强的C语言资料

    60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66...

    C语言难点分析整理

    60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66...

    数据结构(C语言版)综合实践集合运算

    ⑷ 编写集合元素输入并插入到单链表中的函数INSERT_SET,保证所输入的集合中的元素是唯一且以非递减方式存储在单循环链表中; ⑶ 编写求集合A、B的交C=A∩B的函数,并输出集合C的元素; ⑷ 编写求集合A、B的并D=A∪B...

    算法与数据结构实验报告.doc

    二、主要仪器及耗材 普通计算机 三、实验内容与要求 1、用C语言编写一个单链表基本操作测试程序。 (1)初始化单链表 (2)创建单链表 (3)求单链表长度 (4)输出单链表中每一个结点元素 (5)指定位置插入某个...

    学生成绩管理系统课程设计

    学生成绩管理系统,C语言编写,用单链表结点存储信息,已在VC++6.0平台通过测试

    免费下载:C语言难点分析整理.doc

    60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66...

    高级C语言 C 语言编程要点

    60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66...

    上海电机学院C语言实训答案

    实训是在学生已经具备了使用C语言编写简单的应用程序的能力,为使学生对C语言有更全面的理解,进一步提高运用C语言编程解决实际问题的能力,通过提出算法、指定输入输出来设计一个解决方案。并为参加计算机等级考试...

    高级进阶c语言教程..doc

    60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 352 66...

    C语言难点分析整理.doc

    60. 高级C语言程序员测试必过的十六道最佳题目+答案详解 297 61. C语言常见错误 320 62. 超强的指针学习笔记 325 63. 程序员之路──关于代码风格 343 64. 指针、结构体、联合体的安全规范 346 65. C指针讲解 ...

    高级C语言.PDF

    C语言难点分析整理 .......................................................................................................................... 9 3. C语言难点 ..............................................

    c语言经典案例

    实例157 显卡类型测试 204 实例158 获取系统配置信息 206 实例159 访问系统temp中的文件 209 实例160 控制扬声器声音 210 实例161 获取Caps Lock键状态 211 实例162 获取环境变量 212 实例163 贪吃蛇游戏 213 实例...

    二级C语言公共基础知识

    (3) 若按功能划分,软件测试的方法通常分为白盒测试方法和______测试方法。 答:黑盒 (4) 如果一个工人可管理多个设施,而一个设施只被一个工人管理,则实体"工人"与实体"设备"之间存在______联系。 答:一对多#1:...

    C语言实现英文文本词频统计

    这几天写了一个基于C语言对文本词频进行统计的程序,开发及调试环境:mac集成开发环境Xcode;测试文本,马丁.路德金的《I have a dream》原文演讲稿。 主要运行步骤: 1. 打开文本把文本内容读入流中并且开辟相应...

    实验一终稿_基本操作_C++_线性表_

    根据线性表的抽象数据类型的定义,选择下面任一种链式结构实现线性表,并完成线性表的基本功能。...删除4、 查找5、 获取链表长度6、 销毁7、 其他:可自行定义编写测试 main()函数测试线性表的正确性。

    C语言单链队列的表示与实现实例详解

    主要介绍了C语言单链队列的表示与实现,对于研究数据结构与算法的朋友来说很有参考借鉴价值,需要的朋友可以参考下

Global site tag (gtag.js) - Google Analytics