C语言一个单链表的实现

--

list0.c

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

typedef int Item;//定义数据项类型
typedef struct node * PNode;//定义节点指针
//节点的定义
typedef struct node
{
    Item item;//数据域
    PNode next;//链域  

}Node,* SList;  

/*
int SL_Creat(SList *p_list,int size)
参数
p_list:指向一个链表指针,此处传入表头地址
size:要创建的链表分配的数据元素空间个数,不包含头节点
返回值
若成功返回1,否则返回0。
功能
该函数的功能是创建一个大小为size的链表并把链表的头指针赋给p_lsit所指的链表指针。 

*/
int SL_Creat(SList *p_list,int size)
{
    PNode p=NULL;
    int i;  

    *p_list = (SList)malloc(sizeof(Node));
    if(*p_list==NULL)
        return -1;
    (*p_list)->next = NULL;
    for(i=size;i>0;i--)
    {
        p = (PNode)malloc(sizeof(Node));
        if(p==NULL)
            return -1;
        p->item = 0;
        p->next = (*p_list)->next;
        (*p_list)->next = p;
    }
    return 1;
}
/*
int SL_Insert(SList list,int pos,Item item)
参数
list:要插入数据的单链表
int:指定要插入元素的位置,从1开始计数
item:要插入的数据项
返回值
若成功返回1,否则返回-1。
功能
该函数的功能是在链表list的pos位置插入新元素,其值为item。 

*/
int SL_Insert(SList list,int pos,Item item)
{
    PNode p,q;
    int i;  

    p = list;
    i = 0;
    while(p!=NULL && i<pos-1)//将指针p移动到要插入元素位置之前
    {
        p = p->next;
        i++;//i记录p指向的是第几个位置
    }
    if(p==NULL || i > pos-1)
        return -1;
    q = (Node *)malloc(sizeof(Node));//未插入节点分配内存
    if(q!=NULL)//若内存分配成功,将节点插入指定位置
    {
        q->item = item;
        q->next = p->next;
        p->next = q;
        return 1;
    }
    else
    {
        return -1;
    }
}
/*
int SL_GetItem(SList list,int pos,Item *p_item)
参数
list:要获取数据项所在的单链表
int:指定要获取元素在单链表中的位置
p_item:指向要接收数据项的变量
返回值
若成功返回1,否则返回-1。
功能
该函数的功能是获取在链表list的pos位置的元素的数据项,其值赋给p_item所指的变量。 

*/
int SL_GetItem(SList list,int pos,Item *p_item)
{
    PNode p;
    int i;    

    p = list;
    i = 0;
    while(p!=NULL && i<pos)//将指针p移动到要返回的元素位置
    {
        p = p->next;
        i++;//i记录p指向的是第几个位置
    }
    if((p==NULL)||(i>pos))
    {
        return -1;
    }
    *p_item = p->item;
    return 1;
}
/*
int SL_Delete(SList list,int pos,Item * p_item)
参数
list:要删除元素所在的单链表
int:指定要删除元素在单链表中的位置
p_item:指向接收删除元素的数据项的变量
返回值
若成功返回1,否则返回-1。
功能
该函数的功能是删除在链表list的pos位置的元素,其值赋给p_item所指的变量。 

*/
int SL_Delete(SList list,int pos,Item * p_item)
{
    PNode p,q;
    int i;
    p = list;
    i = 0;
    while(p!=NULL && i<pos-1)//将指针p移动到要插入元素位置之前
    {
        p = p->next;
        i++;//i记录p指向的是第几个位置
    }
    if(p->next==NULL || i > pos-1)
        return -1;
    q = p->next;
    p->next = q->next;
    if(p_item != NULL)
        *p_item = q->item;
    free(q);
    return 1;
}
/*
int SL_SetItem(SList list,int pos,Item item)
参数
list:要设置元素所在的单链表
int:指定要设置元素在单链表中的位置
p_item:要设置元素的数据项的值
返回值
若成功返回1,否则返回-1。
功能
该函数的功能是将链表list的pos位置的元素的数据项设置为item。 

*/
int SL_SetItem(SList list,int pos,Item item)
{
    PNode p=NULL;
    int i;
    p = list;
    i = 0;
    while(p!=NULL && i<pos)//将指针p移动到要插入元素位置之前
    {
        p = p->next;
        i++;//i记录p指向的是第几个位置
    }
    if(p==NULL || i > pos)
        return -1;
    p->item = item;
    return 1;  

}
/*
int SL_Find(SList list,int *pos,Item item)
参数
list:要查找元素所在的单链表
int:指向要存储的查得的元素的位置的变量
p_item:要查找元素的数据项的值
返回值
若成功返回1,否则返回-1。
功能
该函数的功能是在链表list中查找数据项为item的元素,将其位置值赋给pos所指的变量。 

*/
int SL_Find(SList list,int *pos,Item item)
{
    PNode p;
    int i;
    p = list;
    i = 0;
    while(p!=NULL && p->item!=item)//将指针p移动到要插入元素位置之前
    {
        p = p->next;
        i++;//i记录p指向的是第几个位置
        if(p->item == item)
        {
            *pos = i; //返回查询到的位置
            return 1;
        }
    }
    return -1;
}
/*
int SL_Empty(SList list)
参数
list:要判断的单链表
返回值
若为空则返回1,否则返回 0。
功能
该函数的功能是判断链表list是否为空表。 

*/
int SL_Empty(SList list)
{
    PNode p;
    p = list;
    if(p->next == NULL)
        return 1;
    return 0;
}
/*
int SL_Size(SList list)
参数
list:要查找的单链表
返回值
返回包含节点的个数。
功能
该函数的功能是返回链表list中节点的个数,包含头节点。 

*/
int SL_Size(SList list)
{
    PNode p;
    int i;  

    p = list;
    i = 0;
    while(p!=NULL)
    {
        p = p->next;
        i++;  

    }
    return i;
}
/*
int SL_Clear(SList *p_list)
参数
p_list:指向要清除的单链表
返回值
成功返回值为1。
功能
该函数的功能是清除链表的所有节点,包含头节点。 

*/
int SL_Clear(SList *p_list)
{
    PNode p,q;
    int i;  

    p = *p_list;
    i = 0;
    while(p!=NULL)
    {
        q = p->next;//借助于q存储p的链域,否则释放p后无法引用
        free(p);
        p = q;
    }
    *p_list = NULL;//将所指的链表指针设为NULL  

    return 1;
}  

list.c

#include"List.h"
#include<malloc.h>
#include<stdlib.h>
/*
List MakeEmpty(List L)
参数
L 要生成的空链表名
返回值
返回生成的空链表名
功能
生成空链表
*/
List MakeEmpty(List L)
{
    L = (PNode)malloc(sizeof(Node));
    L->item = 0;
    L->next = NULL;
    return L;
}  

/*
int IsEmpty(List L)
参数
L 要判定的链表名
返回值
若L为空返回1,否则返回0
功能
判断链表L是否为空
*/
int IsEmpty(List L)
{
    return L->next == NULL;
}
/*
int IsLast(Position P)
参数
P 要判定的位置
返回值
若P为为最后一个节点则返回1,否则返回0
功能
判断位置P的节点是否是链表最后一个节点
*/
int IsLast(Position P)
{
    return P->next == NULL;
}  

/*
Position Find(Item X,List L)
参数
X 要查找的数据项
L 要查找的链表
返回值
若X在L中存在则返回第一个匹配节点的位置,否则返回NULL
功能
判断位置P的节点是否是链表最后一个节点
*/
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)
参数
X 要删除的数据项
L 要删除节点所在的链表
返回值
无
功能
在链表L中删除查找到的第一个数据项为X的节点
*/
void Delete(Item X,List L)
{
    Position P,temp;    /*读者请思考,temp为什么是必要的?*/
    P = FindPrevious(X,L);
    if(!IsLast(P))
    {
        temp = P->next;
        P->next = temp->next;
        free(temp);
    }
}
/*
Position FindPrevious(Item X,List L)
参数
X 要查找的数据项
L 要查找的链表
返回值
若X在L中存在则返回第一个匹配节点的前驱位置,否则返回NULL
功能
返回链表L中数据项为X的节点的前驱节点位置
*/
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)
参数
X 要查找的数据项
L 要查找的链表
返回值
若X在L中存在则返回第一个匹配节点的后继位置,否则返回NULL
功能
返回链表L中数据项为X的节点的后继节点位置
*/
Position FindNext(Item X,List L)
{
    Position P;
    P = L;
    while(P!=NULL && P->item != X)
        P = P->next;
    return P;
}
/*
void Insert(Item X,List L,Position P)
参数
X 要插入的数据项
L 要插入的链表
返回值
无
功能
在链表L中P位置之后插入数据项为X的新节点
*/
void Insert(Item X,List L,Position P)
{
    Position temp;
    temp = malloc(sizeof(Node));
    if(temp==NULL)
        exit(0);
    temp->item = X;
    temp->next = P->next;
    P->next = temp;
}
/*
void DeleteList(List L)
参数
L 要删除节点的链表
返回值
无
功能
删除链表L中除了头节点之外的所有节点
*/
void DeleteList(List L)
{
    Position P,temp;
    P = L->next;
    L->next = NULL;
    while( P!=NULL)
    {
        temp = P->next;
        free(P);
         P = temp;
    }
}
/*
Position Header(List L)
参数
L 要查找的链表
返回值
返回链表L的头节点位置
功能
返回头节点
*/
Position Header(List L)
{
    return L;
}
/*
Position First(List L)
参数
L 要查找的链表
返回值
若链表非空则返回第一个数据节点,否则返回NULL
功能
返回第一个数据节点位置
*/
Position First(List L)
{
    if(L->next!=NULL)
    return L->next;
}
/*
Position Advance(Position P)
参数
P 当前节点位置
返回值
若P位置后继节点存在则返回其位置,否则返回NULL
功能
获得位置P后继节点位置
*/
Position Advance(Position P)
{
    if(P!=NULL)
    return P->next;
}
/*
Item Retrieve(Position P)
参数
P 当前节点位置
返回值
若P非空则返回其数据项的值
功能
返回P位置的数据项
*/
Item Retrieve(Position P)
{
    if(P!=NULL)
    return P->item;
}  

list.h

#ifndef List_H
#define List_H
typedef int Item;/*定义数据项类型*/
typedef struct node * PNode;/*定义节点指针*/  

typedef struct node/*节点的定义*/
{
    Item item;  /*数据域*/
    PNode next; /*链域*/  

}Node;  

typedef  PNode Position;
typedef  PNode List;  

List MakeEmpty(List L);
/*
功能
生成空链表L
*/
int IsEmpty(List L);
/*
功能
判定链表是否为空
*/
int IsLast(Position P);
/*
功能
判定位置P的节点是否为尾节点
*/
Position Find(Item X,List L);
/*
功能
在链表L中查找数据项为X的第一个节点
*/
void Delete(Item X,List L);
/*
功能
在链表L中删除数据项为X的第一个节点
*/
Position FindPrevious(Item X,List L);
/*
功能
在链表L中查找数据项为X的第一个节点的前驱位置
*/
Position FindNext(Item X,List L);
/*
功能
在链表L中查找数据项为X的第一个节点的后继位置
*/
void Insert(Item X,List L,Position P);
/*
功能
在链表L中P位置插入数据项为X的节点
*/
void DeleteList(List L);
/*
功能
删除链表L初头节点外的所有节点
*/
Position Header(List L);
/*
功能
获得链表L中头节点位置
*/
Position First(List L);
/*
功能
获得链表L中第一个数据节点的位置
*/
Position Advance(Position P);
/*
功能
获得P位置的后继节点位置
*/
Item Retrieve(Position P);
/*
功能
获得P位置节点的数据项
*/
#endif  

main.c

#include"List.h"
#include<stdlib.h>
int main()
{
    List list=NULL;
    Position p;
    int i;
    list = MakeEmpty(list);
    printf("已生成空链表list\n");
    if(IsEmpty(list))
    printf("经检验list是个空链表\n");  

    p = list;
    for(i=0;i<5;i++)
    {
        Insert(i*i,list,p);
        p = Advance(p);
        printf("已插入的值为%d新节点\n",Retrieve(p));
    }
    p = FindNext(9,list);
    printf("数据项为9的节点后继的数据项值为%d\n",Retrieve(p));  

    p = FindPrevious(9,list);
    printf("数据项为9的节点前驱的数据项值为%d\n",Retrieve(p));  

    Delete(9,list);  

    p = list;
    for(i=0;i<4;i++)
    {
        p = Advance(p);
        printf("删除数据项为9的节点剩下的节点值为%d\n",Retrieve(p));
    }  

    DeleteList(list);
    printf("已删除链表list的所以数据节点\n");
    if(IsEmpty(list))
    printf("经检验list是个空链表\n");  

}  

--

原创:

http://blog.csdn.net/hopeyouknow/article/details/6711216

--

时间: 2024-11-23 01:13:36

C语言一个单链表的实现的相关文章

C语言实现单链表节点的删除(带头结点)

我在之前一篇博客<C语言实现单链表节点的删除(不带头结点)>中具体实现了怎样在一个不带头结点的单链表的删除一个节点,在这一篇博客中我改成了带头结点的单链表.代码演示样例上传至 https://github.com/chenyufeng1991/DeleteLinkedList_HeadNode.删除类型有两种: (1)删除某个位置pos的节点: (2)推断x值是否在链表中,若存在则删除该节点: 核心代码例如以下: //删除某个位置pos的节点 Node *DeletePosNode(Node

「C语言」单链表/双向链表的建立/遍历/插入/删除

最近临近期末的C语言课程设计比平时练习作业一下难了不止一个档次,第一次接触到了C语言的框架开发,了解了View(界面层).Service(业务逻辑层).Persistence(持久化层)的分离和耦合,一种面向过程的MVC的感觉. 而这一切的基础就在于对链表的创建.删除.输出.写入文件.从文件读出...... 本篇文章在于巩固链表的基础知识(整理自<C语言程序设计教程--人民邮电出版社>第十章),只对链表的概念及增删改查作出探讨,欢迎指教. 一.链表结构和静态/动态链表 二.单链表的建立与遍历

C语言实现单链表(带头结点)的基本操作

我在之前一篇博客<C语言实现单链表(不带头结点)的基本操作>中具体实现了不带头结点的单链表的11种操作:如计算链表长度.初始化.创建链表.清空链表等等.但是在实际使用中,带头结点的单链表往往比不带头结点的单链表用的更多,使用也更为方便.因为不用单独考虑第一个节点的情况了,第一个节点和其他后续节点的处理全都一样了,简化操作.这篇博客将会来实现带头结点的单链表的11种操作.代码上传至: https://github.com/chenyufeng1991/LinkedList_HeadNode  .

C语言实现单链表-03版

在C语言实现单链表-02版中我们只是简单的更新一下链表的组织方式: 它没有更多的更新功能,因此我们这个版本将要完成如下功能: Problem 1,搜索相关节点: 2,前插节点: 3,后追加节点: 4,一个专门遍历数据的功能: Solution 我们的数据结构体定义如下,和上一个版本稍微有所不同: 例如,我们把人这个结构体添加一个name域,前几个版本没有名字的节点: 我们叫起来很尴尬,都是第几个第几个节点,好啦!现在有名字啦! #include <stdio.h> #include <s

C语言实现单链表-02版

我们在C语言实现单链表-01版中实现的链表非常简单: 但是它对于理解单链表是非常有帮助的,至少我就是这样认为的: 简单的不能再简单的东西没那么实用,所以我们接下来要大规模的修改啦: Problem 1,要是数据很多怎么办,100000个节点,这个main函数得写多长啊... 2,这个连接的方式也太土啦吧!万一某个节点忘记连接下一个怎么办... 3,要是我想知道这个节点到底有多长,难道每次都要从头到尾数一遍嘛... 4,要是我想在尾部添加一个节点,是不是爬也要爬到尾部去啊... 这个是简单版中提出

单链表的插入伪算法和用C语言创建单链表,并遍历

非循环单链表插入结点伪算法讲解 q插入p之后的伪算法:第一种表示方法:r = p->pNext; // p->pNext表示的是所指向结点的指针域,指针域又是指向下一个结点的地址p->pNext = q; // q保存了那一块结点的地址.q是一个指针变量,存放那个结点的地址.q->pNext = r; 第二种表示方法:q->pNext = p->pNext; // q的指针域指向p后面一个结点p->pNext = q; // p的指针域指向q 删除非循环单链表结点

7_1判断一个单链表是否有环

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4251303.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:判断一个单链表是否有环,如果有环,求出环的入口节点. 题目分析: 建一个待头节点的单链表,有两个指针p,q最开始都指向第一个真正节点,p,诶次走1步,q每次走

【练习题】编写打印出一个单链表的所有元素的程序【链表】

只是实现了链表ADT的部分功能. /*---编写打印出一个单链表的所有元素的程序---*/ #include <stdio.h> #include <stdlib.h> struct Node{ int val; struct Node *next; }; Node *findEnd(Node *list){ while(list->next) list = list->next; return list; } void insert(int val, Node *li

实现一个算法从一个单链表中返回倒数第n个元素(keep it up)

我们维护两个指针, 它们之间的距离为n.然后,我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变.那么, 当第二个指针指到空时,第一个指针即为所求. #include <iostream> struct Node { int data; Node* next; }; void initList(Node* vNode) { for (int i=0; i < 20; ++i) { Node* TempNode = new Node; TempNode->data =