链表

线性表链式存储结构通过“链”建立起数据元素之间的逻辑关系,这种用链接方式的线性表简称链表(Link List),在链表上做插入、删除运算不需要移动数据元素。


顺序表和链表的比较

顺序表的优点:

(1)用数组存储数据元素,操作方法简单,容易实现。

(2)不用为表示结点间的逻辑关系而增加额外的存储开销。

(3)存储密度高。

(4)可以随机访问(使用下标访问)。

顺序表的缺点:

(1)做插入,删除操作时,要大量地移动数据元素,效率比较低。

(2)要占用连续的存储空间,且大小要固定,不适合动态存储。


链表的优点:

(1)插入、删除操作简单

(2)大小可变,适合动态存储。

链表的缺点:

(1)查找效率低。

(2)不支持随机存储。

#include<stdio.h>
#include<stdlib.h>
/*
结点定义 
*/
typedef int ElemType;

typedef struct node{
	ElemType data;			//数据域
	struct node *next; 		//指针域 
}LNode, *LinkList;
 
 /*
 单链表的建立
 单链表的建立有两种方法:在链表的头部插入结点和在链表的尾部插入结点(头插法和尾插法)。 
 */
 //头插法建立单链表
 LinkList creat_LinkList1(){
 	LinkList H = (LinkList)malloc(sizeof(LNode));	//生成头结点。
	LNode *s;
	H->next = NULL;									
	int x;											//设数据元素的类型为int
	scanf("%d", &x);
	while(x != -1){
		s = (LinkList)malloc(sizeof(LNode));
		s->data = x;
		s->next = H->next;
		H->next = s;
		scanf("%d", &x);
	}
	 return H;
 }
 //尾插法建立单链表
 LinkList creat_LinkList2(){
 	LinkList H = (LinkList)malloc(sizeof(LNode));
 	H->next = NULL;
 	LNode *s, *r = H;
 	int x;
 	scanf("%d", &x);
 	while(x != -1){
 		s = (LinkList)malloc(sizeof(LNode));
 		s->data = x;
 		s->next = r->next;
 		r->next = s;
 		r = s;
 		scanf("%d", &x);
	 }
	 return H;
 } 
 
 
 //求表长
 /*
 思路:设一个指针p和计数器length,初始化使p指向头结点H,j = 0。若p所指结点还有后继结点,
 p向后移动,计数器加1(长度不包括头结点),重复上述过程,直到p->next=NULL为止。 
 */ 
 int length_LinkList(LinkList H){
 	LNode *p = H;
 	int length = 0;
 	while(p->next != NULL){
 		p = p->next;
 		length++;
	 }
	 return length;
 } 
 
 //查找操作
 /*
 按序号查找 
 思路:从链表的第一个元素结点开始判断当前结点是否是dik个,若是,则返回该结点的指针,
 否则继续查找下一个,直到表结束为止。没有第k个节点是返回空。 
 */ 
 LNode * get_LinkList(LinkList H, int k){
 	LNode *p = H;
	 int j = 0;
	 while(p->next != NULL && j < k){
	 	p = p->next;
	 	j++;
	 } 
	 if(j == k){
	 	return p;
	 }else{
	 	return NULL;
	 }
 } 
 /*
 按值查找
 思路:从链表的第一个元素结点开始=,判断当前结点的值是否等于x,若是, 
 返回该结点的指针,否则继续向后查找,直到表结束为止,若查找不到则返回空。 
 */
 LNode * locate_LinkList(LinkList H, ElemType x) {
 	LNode * p = H->next;
 	while(p != NULL && p->data != x){
 		p = p->next;
	 }
	 return p;
 }
 //单链表的插入
 //在单链表H的第i个位置上插入值为x的元素 
 int insert_LinkList(LinkList H, int i, ElemType x){
 	LNode *p, *s;
	p = get_LinkList(H, i-1);
	if(p == NULL){
		printf("插入位置i错误");
		return -1; 
	} else{
		s = (LinkList)malloc(sizeof(LNode));
		s->data = x;
		s->next = p->next;
		p->next = s;
		return 0;
	}
 } 
 //删除操作
 
 int del_LinkList(LinkList H, int i){
 	LinkList p, q;
 	p = get_LinkList(H, i-1);
 	if(p == NULL){
 		printf("第i-1个结点不存在");
 		return -1;
	 }else{
	 	if(p->next == NULL){
	 		printf("第i个结点不存在");
	 		return -1;
		 }else{
		 	q = p->next;
		 	p->next = q->next;
		 	free(q);
		 	return 0;
		 }
	 }
 } 
 //单链表的倒置
/*
思路:链表建立时,采用尾插法建立的链表和输入的顺序相反。 
*/ 
void reverse(LinkList H){
	LNode *p, *q;
	p = H->next;
	H->next = NULL;
	while(p){
		q = p;
		p = p->next;
		q->next = H->next;
		H->next = q;
	}
}  



 void print_LinkList(LinkList H){
 	LinkList p = H->next;
 	while(p != NULL){
 		printf("%d ",p->data);
 		p = p->next;
	 }
	 printf("\n");
 } 
 
int main(void){
	LinkList H = creat_LinkList2();
	print_LinkList(H);
//	int length = length_LinkList(H);
//	printf("%d\n", length);
//	LNode *p = get_LinkList(H, 5);
//	if(p != NULL)
//	printf("%d", p->data);
//	insert_LinkList(H, 4, 4);
//	print_LinkList(H);
//	del_LinkList(H, 4);
	reverse(H);
	print_LinkList(H);
	return 0;
} 




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值