线性表的链式实现C语言

对于我来说学习线性表的链式实现最大的阻碍就是C语言的指针语法,关于其中有两个函数是利用了指针的指针,真是让我头疼了好久,寻思全部靠自己和书自己写,但是最终还是看了一下“范文”,才搞明白为什么总是不好使,
第一个疑惑:对于InitLinkList的返回值是LNode*,我还是有点疑惑的,我曾经把定义好的结构体指针作为参数,但是并不能完成所有函数的功能,只有这样才可以。

第二个疑惑:是clearList的函数,这个我也是有疑问的,但是“范文”找不到,疑惑就是,clear这个链表但是并没有销毁我的头结点,但是我的头结点地址不见了,

第三个困惑就是:链表的头结点的地址在不断的变化,emmmm,可能还是我的操作有问题。

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

#define TRUE  	  1
#define FALSE 	  0
#define OK     	  1
#define ERROR     0
#define OVERFLOW -2 

typedef int status;

typedef struct LNode{
	int data;
	struct LNode *next;
}LNode;

LNode* InitLinkList(); 			    //单链表的初始化
status ListInsert(LNode **L, int i, int e);  //在L中第i个位置之前插入数据元素e 
status ListEmpty(LNode *L); 	 			//判断链表是否为空 
status DestroyList(LNode *L);  			    //销毁单链表
status GetElem(LNode *L, int i, int *e);    //获取线性表中某个数据元素的内容,通过e返回 
status LocateElem_i(LNode *L, int e);		//查找元素的位置
LNode* LocateElem(LNode *L, int e); 	    //查找元素的位置 
status ListDelete(LNode *L, int i, int *e); //删除指定位置元素 
status CreateList_H(LNode **L, int n);       //头插法   
status CreateList_R(LNode **L, int n);       //尾插法 
status ListLength(LNode *L); 	 			//求单链表的表长
status ListVisit(LNode *L);                 //遍历  


int main(){
	LNode *link;
	link = InitLinkList();
//	printf("%p\n", link); 
//	ListInsert(&link, 1, 1);
//	ListInsert(&link, 1, 2);
//	printf("%d\n", link->next->data);
//	printf("%d\n", link->next->next->data);
//	printf("%d\n", ListLength(link));
//	ListVisit(link);
//	printf("\n");
//	printf("%d\n", ListEmpty(link));
//	int elem;
//	GetElem(link, 1, &elem);
//	printf("%d\n", elem);
//	CreateList_H(&link, 2);
//	printf("%d\n", link->next->data);
//	printf("%d\n", link->next->next->data);
	CreateList_R(&link, 2);
	printf("%d\n", link->next->data);
	printf("%d\n", link->next->next->data);
//	DestroyList(link);
	
	
	
	
	return 0;
} 

LNode* InitLinkList(){
	//生成新结点作头结点,用头指针L指向头结点 
	LNode *L = (LNode*)malloc(sizeof(LNode));
	if(!L){
		return ERROR;
	}
	//将头结点的指针域置为空 
	L->next = NULL;

	return L;
}

status ListInsert(LNode **L, int i, int e){
	LNode *p = (LNode*)malloc(sizeof(LNode));
	p = *L;
	int j = 0;
	//寻找到位置 
	while(p != NULL && j < i-1){
		p = p->next;
		j++;
	}
	//不合法 
	if(!p || j > i-1){
		return ERROR;
	}
	LNode *s = (LNode*)malloc(sizeof(LNode));
	//生成新节点将数据域置为e 
	s->next = NULL;
	s->data = e;
	//将节点s插入L中 
	s->next = p->next;
	p->next = s;
	
	return OK;
}

status ListEmpty(LNode *L){
	//空链表返回1,非空链表返回0 
	if(L->next == NULL){
		return TRUE;
	}else{
		return FALSE;
	}
}

status DestroyList(LNode *L){
	//从头指针开始依次释放所有结点 
	LNode *p = (LNode*)malloc(sizeof(LNode));
	
	while(L != NULL){
		p = L;
		L = L->next;
		free(p);
	}
	
	return OK;
}

status ListLength(LNode *L){
	LNode *p = (LNode*)malloc(sizeof(LNode));
	//暂时 
	p = L;
	//计数器 
	int nums = 0;
	if(ListEmpty(L) == TRUE){
		return 0;
	}
	//遍历单链表,统计节点数 
	while(p->next != NULL){
		nums++;
		p = p->next;
	}
	
	return nums;
}

status GetElem(LNode *L, int i, int *e){
	LNode *p = (LNode*)malloc(sizeof(LNode));
	//暂时的寄存器,目前为第一个元素的内容
	p = L->next;  
	//计数器,目前为1
	int j = 1;    
	//顺指针向后查找,直到p指向第i个元素或p为空 
	while(p != NULL && j < i){
		p = p->next;
		j++;
	}
	//第i个元素不存在 
	if(!p || j > i){
		return ERROR;
	} 
	//取第i个元素 
	*e = p->data;

	return OK;
}

LNode* LocateElem(LNode *L, int e){
	//在线性表中查找值为e的数据元素
	//找到则返回地址,否则返回NULL 
	LNode *p = (LNode*)malloc(sizeof(LNode));
	p = L->next;
	
	while(p != NULL && p->data != e){
		p = p->next;
	}
	
	return p;
}

status LocateElem_i(LNode *L, int e){
	//返回L中值为e的数据元素的位置序号 
	LNode *p = (LNode*)malloc(sizeof(LNode));
	p = L->next;
	int j = 1;
	
	while(p != NULL && p->data != e){
		p = p->next;
		j++;
	}
	
	if(p != NULL){
		return j;
	}else{
		return 0;
	}
	
}

status ListDelete(LNode *L, int i, int *e){
	LNode *p = (LNode*)malloc(sizeof(LNode));
	LNode *q = (LNode*)malloc(sizeof(LNode));
	p = L;
	int j = 0;
	//寻找第i个节点,并令p指向其前驱元素 
	while(p->next && j < i-1){
		p = p->next;
		j++;
	}
	if(!(p->next) && j > i-1){
		return ERROR;
	}
	q = p->next;
	p->next = q->next;
	*e = q->data;
	free(q);
	
	return OK;
}

status ListVisit(LNode *L){
	LNode *p = (LNode*)malloc(sizeof(LNode));
	
	p = L->next;
	
	while(p){
		printf("%d", p->data);
		p = p->next;
	}
	
	return OK;
} 

status CreateList_H(LNode **L, int n){
	//先建一个带头结点的单链表 
	*L = (LNode*)malloc(sizeof(LNode));
	(*L)->next = NULL;
	int i = 0;
	//插入到表头 
	for(i = 0; i < n; i++){
		LNode *p = (LNode*)malloc(sizeof(LNode));
		printf("NO.%d:",i+1);
		scanf("%d", &(p->data));
		p->next = (*L)->next;
		(*L)->next = p; 
	}
	
	return OK;
	
}

status CreateList_R(LNode **L, int n){
	*L = (LNode*)malloc(sizeof(LNode));
	(*L)->next = NULL;
	LNode *r = *L;//尾指针r指向头结点 
	int i = 0;
	for(i = 0; i < n; i++){
		LNode *p = (LNode*)malloc(sizeof(LNode));
		printf("NO.%d:",i+1);
		scanf("%d",&(p->data));	
		p->next = NULL;
		r->next = p;
		r = p;	
	}
	
	return OK;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值