用C语言实现无头单链表学习心得


首先讲第一种无头单头不循环的单链表
是通过指向单链表头结点的结构题指针来维护的

//定义单链表结点

typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SListNode;

typedef struct SListNode* SList;

//控制单链表的方法(接口)



void SListInit(SList* head);      //SList  就是struct SListNode**,二级指针
void SListDestory(SList* head);
void SListShow(const SList* head);
…………

主函数

int main()
{
SList head; //创建指向单链表结构体的指针
SListInit(&head)//head是SList即struct SListNode*类型, &head则要用二级指针接收

在这里提一下为什么传指向单链表结点的指针的地址并用二级指针接收
如果直接传指向单链表结点的指针

分两种情况

第一种head头指针指向空头指针无法访问到任何结点,指针是按值传参所以也无法改变head头					     			    						    
指针的指向, 这将导致灾难性的后果这个单链表注定永生孤独,永远是一个空链表,无法初始化  
且无法添加任何结点

 第二种head头指针本身就指向一段大于等于一个结点的单链表则其可以访问到存在的任何结点 
只不过head头指针只能访问指向的数据, 但永远无法改变head头指针的指向,调用的方法传入
的只是head指针的一份临时拷贝无论对拷贝变量如何修改都无法改变链表的结构,即无法对链表	
进行增删改查的任何操作

return 0;
}


再讲第二种无头单向不循环的单链表
也是通过指向单链表头结点的结构题指针来维护的,只不过区别是将head指针再装到一个结构体中,调用单链表的方法时,便可以传这个装了head指针的结构体的地址,并用指向装head指针的结构体的指针去接收,这样就巧妙的避开二级指针使用不熟练的硬伤以及会出现的各种指针危险,也不会纠结改变链表结构的传址,不该变链表结构的传值

(其实不该变实参的形参设置有两种方法:如下)

不该变实参的形参设置有两种方法
(1)传值 形参用与实参相同的类型接收
(2)传址 形参用const 的指针来接收(注意const位于*前的两种情况)

注意:const的使用
const 修饰指针类型可以出现在三个位置分两种情况(前和后)

例:void*   b;
const void*   b;    //在指针指向的类型名前
void   const*   b;   //在*前面
void*  const b;     //在变量名前

const*前(前两种位置),指针指向的内存无法被修改
const*后(最后一种位置情况),指针的指向无法被修改

第二种无头单向不循环的单链表如下:
//定义单链表结点





typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SListNode;

//定义装了head指针的结构体
typedef struct SList
{
	SListNode* _head;
}SList;
typedef struct SList*   Head;

//控制单链表的方法(接口)
void SListInit(Head* head);      //SList  就是struct SListNode**,二级指针
void SListDestory(Head* head);
void SListShow(const Head* head);
…………


int main()
{
SList head; //实例化装了head指针的结构体
SListInit(&head)//head是SList即struct SList类型, &head则要用一级指针 struct SList*即
Head接收
在维护链表的方法中,head->_head即是访问整个结构体的那个重要的头指针
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三种不同的方法,挺不错的! #include<stdio.h> #include<stdlib.h> #include<string.h> #define N 100 typedef struct SList { char data[N]; //字符数组 struct SList *next; //定义链表指针 }SList,*ListPointer; /*typedef struct List { SList *head; }List,* ListPointer; */ void initList(ListPointer &lp) { lp=(SList *)malloc(sizeof(SList));//初始化链表 lp->next=lp; //链表指针指向本身,实现链表循环 } void output(ListPointer lp) // 自定义输出函数 { SList *ep; ep=lp; while(ep->next!=lp) //判定条件 当指针重新指向指针输出结束 { ep=ep->next; printf("%s ",ep->data); } } void revert(ListPointer lp) // 链表的逆置 { SList *p,*q; p=lp;q=NULL;lp=NULL; while(p) { q=p->next; p->next=lp; lp=p; p=q; } /*方法二 SList *p,*q,*end; p=lp->next; q=p->next; end=p; while(q!=lp) { lp->next=q; q=q->next; lp->next->next=p; p=lp->next; } end->next=lp; */ } void add_char(char *p,ListPointer lp) //将输入的字符传递给链表 { SList * ep; ep=lp; while(ep->next!=lp) //判定条件 当指针重新指向指针输出结束 { ep=ep->next; } ep->next=(SList *)malloc(sizeof(SList)); //开辟空间存储 strcpy(ep->next->data,p); //字符的传递 ep->next->next=lp; } void main() { ListPointer L; char str[N]; initList(L); printf("输入#以结束\n");//确定输入终止条件 while(1) { scanf("%s",str); if(*str=='#') //判定条件 { break; } add_char(str,L); } printf("初始序列为:"); output(L); printf("\n"); revert(L); printf("逆置后为:"); output(L); printf("\n"); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值