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 -;
(*p_list)->next = NULL;
for(i=size;i>;i--)
{
p = (PNode)malloc(sizeof(Node));
if(p==NULL)
return -;
p->item = ;
p->next = (*p_list)->next;
(*p_list)->next = p;
}
return ;
}
/*
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 = ;
while(p!=NULL && i<pos-)//将指针p移动到要插入元素位置之前
{
p = p->next;
i++;//i记录p指向的是第几个位置
}
if(p==NULL || i > pos-)
return -;
q = (Node *)malloc(sizeof(Node));//未插入节点分配内存
if(q!=NULL)//若内存分配成功,将节点插入指定位置
{
q->item = item;
q->next = p->next;
p->next = q;
return ;
}
else
{
return -;
}
}
/*
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 = ;
while(p!=NULL && i<pos)//将指针p移动到要返回的元素位置
{
p = p->next;
i++;//i记录p指向的是第几个位置
}
if((p==NULL)||(i>pos))
{
return -;
}
*p_item = p->item;
return ;
}
/*
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 = ;
while(p!=NULL && i<pos-)//将指针p移动到要插入元素位置之前
{
p = p->next;
i++;//i记录p指向的是第几个位置
}
if(p->next==NULL || i > pos-)
return -;
q = p->next;
p->next = q->next;
if(p_item != NULL)
*p_item = q->item;
free(q);
return ;
}
/*
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 = ;
while(p!=NULL && i<pos)//将指针p移动到要插入元素位置之前
{
p = p->next;
i++;//i记录p指向的是第几个位置
}
if(p==NULL || i > pos)
return -;
p->item = item;
return ; }
/*
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 = ;
while(p!=NULL && p->item!=item)//将指针p移动到要插入元素位置之前
{
p = p->next;
i++;//i记录p指向的是第几个位置
if(p->item == item)
{
*pos = i; //返回查询到的位置
return ;
}
}
return -;
}
/*
int SL_Empty(SList list)
参数
list:要判断的单链表
返回值
若为空则返回1,否则返回 0。
功能
该函数的功能是判断链表list是否为空表。 */
int SL_Empty(SList list)
{
PNode p;
p = list;
if(p->next == NULL)
return ;
return ;
}
/*
int SL_Size(SList list)
参数
list:要查找的单链表
返回值
返回包含节点的个数。
功能
该函数的功能是返回链表list中节点的个数,包含头节点。 */
int SL_Size(SList list)
{
PNode p;
int i; p = list;
i = ;
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 = ;
while(p!=NULL)
{
q = p->next;//借助于q存储p的链域,否则释放p后无法引用
free(p);
p = q;
}
*p_list = NULL;//将所指的链表指针设为NULL return ;
}
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 = ;
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();
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=;i<;i++)
{
Insert(i*i,list,p);
p = Advance(p);
printf("已插入的值为%d新节点\n",Retrieve(p));
}
p = FindNext(,list);
printf("数据项为9的节点后继的数据项值为%d\n",Retrieve(p)); p = FindPrevious(,list);
printf("数据项为9的节点前驱的数据项值为%d\n",Retrieve(p)); Delete(,list); p = list;
for(i=;i<;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
--
C语言一个单链表的实现的更多相关文章
- c语言,递归翻转一个单链表,c实现单链表
目的:主要是练习c里面单链表的实现,递归思想复习; #include <stdlib.h> #include <stdio.h> typedef struct _Node{// ...
- C语言实现单链表-03版
在C语言实现单链表-02版中我们只是简单的更新一下链表的组织方式: 它没有更多的更新功能,因此我们这个版本将要完成如下功能: Problem 1,搜索相关节点: 2,前插节点: 3,后追加节点: 4, ...
- C语言实现单链表-02版
我们在C语言实现单链表-01版中实现的链表非常简单: 但是它对于理解单链表是非常有帮助的,至少我就是这样认为的: 简单的不能再简单的东西没那么实用,所以我们接下来要大规模的修改啦: Problem 1 ...
- 「C语言」单链表/双向链表的建立/遍历/插入/删除
最近临近期末的C语言课程设计比平时练习作业一下难了不止一个档次,第一次接触到了C语言的框架开发,了解了View(界面层).Service(业务逻辑层).Persistence(持久化层)的分离和耦合, ...
- C语言实现单链表,并完成链表常用API函数
C语言实现单链表,并完成链表常用API函数: 1.链表增.删.改.查. 2.打印链表.反转打印.打印环形链表. 3.链表排序.链表冒泡排序.链表快速排序. 4.求链表节点个数(普通方法.递归方法). ...
- C语言实现单链表节点的删除(带头结点)
我在之前一篇博客<C语言实现单链表节点的删除(不带头结点)>中具体实现了怎样在一个不带头结点的单链表的删除一个节点,在这一篇博客中我改成了带头结点的单链表.代码演示样例上传至 https: ...
- C/C++语言实现单链表(带头结点)
彻底理解链表中为何使用二级指针或者一级指针的引用 数据结构之链表-链表实现及常用操作(C++篇) C语言实现单链表,主要功能为空链表创建,链表初始化(头插法),链表元素读取,按位置插入,(有序链表)按 ...
- LeetCode 笔记系列六 Reverse Nodes in k-Group [学习如何逆转一个单链表]
题目:Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. ...
- 单链表的插入伪算法和用C语言创建单链表,并遍历
非循环单链表插入结点伪算法讲解 q插入p之后的伪算法:第一种表示方法:r = p->pNext; // p->pNext表示的是所指向结点的指针域,指针域又是指向下一个结点的地址p-> ...
随机推荐
- .net面试题汇总一第一篇
1. 简述 private. protected. public. internal 修饰符的访问权限. private:私有成员,只能在类内部中才可以访问. protected:受保护的,只能在该类 ...
- MVC 上传文件的方法
这两天又开始研究MVC了,期间断断续续已经搞了好久了,可是都没坚持下来.囧!这次一定坚持搞出来一个名堂. 废话少说,直接上代码. 前台引擎采用Razor @model System.Web.HttpP ...
- [MFC] TabControl选项卡的使用
MFC中,因项目需要使用TabControl ,使用过程中发现,MFC中的TabControl与C#的TabControl不同,不能通过属性来创建选项页,只能代码生成绑定. 以下为具体的实现方法步骤: ...
- HDU 5001 Walk (暴力、概率dp)
Walk Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Sub ...
- msp430项目编程51
msp430综合项目---扩展项目一51 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结
- Android Studio一些常用的快捷键
光标移动和窗口切换:1.esc:光标从功能窗口回到编辑窗口 2.alt+num:打开指定的功能窗口,重复操作关闭该窗口. 3.alt+←→:切换编辑的文件. 4.ctrl+home/end:跳转到文件 ...
- [Node.js] Trigger a File Download in Express
Downloading and saving a file is a common scenario when building out your web application. Using Exp ...
- poj 1694 An Old Stone Game 树形dp
//poj 1694 //sep9 #include <iostream> #include <algorithm> using namespace std; const in ...
- Android studio 导入githubproject
Blog From:http://blog.csdn.net/onlysnail/article/details/45115093 从github下载两个开源项目: PagerSlidingTabSt ...
- Meteor 从一个列表页进入详情页怎样高速显示详情
无论是做android开发,还是做网页web开发,都 会有列表,都须要点击列表进入列表项的详情页面,查看具体信息,能常情况下,我们都是将这一列表项的id传到详情页,由详情页再到数据库查询具体信息. 在 ...