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));
    
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值