数据结构-单链表的创建

线性表的链式存储-单链表,可以解决顺序表需要大量连续存储单元的缺点,但是由于增加了指针域,所以也存在浪费存储空间的缺点,不具备随机存取的特点,查找时,必须遍历链表。

头结点:带头结点的链表的第一个结点

头结点一般不存储信息

含有头结点和不含头结点的区别:

①第一个含有数据的结点实际为链表的第二个结点,简单来说就是方便了插入删除等操作,不用在进行特殊处理。

②含有头结点,无论单链表是否为空,头指针始终指向头结点,就是链表是否为空已经不重要了。

1.含有头结点的头插法

头插法:每次生成的新结点都插入到头结点之后,也就是放在表头,比如,本来链表里的数据是:2 1 3,然后插入4,此时就变成了,4 2 1 3;时间复杂度,插入一次为O(1),单链表长为你,O(n)

2.不含头结点的头插法

不含头结点,当L为空时(记得初始化L=NULL),直接将新结点的地址赋给L,L!=NULL时,在头部插入新结点后,再将新结点的地址赋给L,(L作为第一个结点)。

3.含有头结点的尾插法

尾插法:一般增加一个尾指针t,始终指向尾结点,方便在最后一个结点后插入新的结点,如果不使用尾指针,就需要每次遍历链表,到表尾插入,时间复杂度大大增加;而含有尾指针的时间复杂度和头插法一样O(n)

4.不含头结点的尾插法

插入第一个结点时,将新结点的地址赋给L,再将L的地址赋给尾结点t,之后依次往表尾插入即可。

完整代码

#include<cstdio>
#include<iostream>

using namespace std;

typedef int ElemType;

typedef struct LNode{
	ElemType data;  //存储数据
	struct LNode *next; 
}*LinkNode;
LinkNode headCreateLNode(LinkNode &L){		//含有头结点的头插法 
	int e;
	L = (LNode*)malloc(sizeof(LNode));
	L->next = NULL;
	LNode *s;
	cin>>e;
	while(e!=-1){
		s = (LNode*)malloc(sizeof(LNode));
		s->data = e;
		s->next = L->next;
		L->next = s;
		
		cin>>e;
	}
	return L;
}
LinkNode noheadCreateLinkNode(LinkNode &L){		不含头结点的头插 
	int e; 
	//L = (LNode *)malloc(sizeof(LNode));
	//L->next = NULL;
	LinkNode s; 
	cin>>e;
	while(e!=-1){
		s=(LinkNode)malloc(sizeof(LNode));
		s->data = e;
		s->next = NULL;
		cout<<"hahaha\n";
		if(L==NULL){
			L=s;
		}else{
			s->next = L;
			L = s;
		}
		cin>>e;
	}
	
	//L->next = NULL;	//有了这行代码,L的下一个节点直接变成NULL,只能输出一个元素 
	
	return L;
}
LinkNode tailCreateLinkNode(LinkNode L){		//含有头结点的尾插 
	LinkNode s;
	
	int e;
	L = (LinkNode)malloc(sizeof(LNode));
	LinkNode t = L;  //尾结点
	cin>>e;
	while(e!=-1){
		s = (LNode*)malloc(sizeof(LNode));
		s->data = e;
		t->next = s;
		t = s;
		cin>>e;
	} 
	t->next = NULL;
	return L;
} 
void tailNoHeadNodeCreateLNode(LinkNode &L){		//这里不加头结点或者尾结点都需要遍历链表 
	LinkNode s,t; 
	int e;
	if(L==NULL) cout<<"yes\n";		//新创建出来的 L3!=NULL 
	else {
		cout<<"NO\n";
	}
	L=NULL;
	cin>>e;
	while(e!=-1){
		s=(LinkNode)malloc(sizeof(LNode));
		s->data = e;
		s->next = NULL;
		if(L==NULL){
			L = s;
			t = L;	
		}else{
			t->next = s;
			t = s;
		}
		cin>>e;
	}
	t->next = NULL; //t作为尾结点,最后指向NULL
	 
} 
void printLNode(LinkNode L){		//没有头结点的输出也不一样 
	L=L->next;
	if(L==NULL){
		cout<<"error\n";
	}
	while(L){
		cout<<L->data<<" ";
		L=L->next;
	}
}
void printNoHeadNode(LinkNode L){		//没有头结点的输出也不一样 
	//L=L->next;
	if(L==NULL){
		cout<<"error\n";
	}
	while(L){
		cout<<L->data<<" ";
		L=L->next;
	}
}
int main()
{
	LinkNode L,L1,L2,L3;
	L3 = NULL;
    L1 = NULL;
	//cout<<L<<" "<<L1<<" "<<L2<<" "<<L3<<endl; 
	headCreateLNode(L); 		//头结点头插 
	printLNode(L);
	
	L1 = tailCreateLinkNode(L1);		//头结点尾插 
	printLNode(L1);
	
	L2 = noheadCreateLinkNode(L2);
	printNoHeadNode(L2);
	
	tailNoHeadNodeCreateLNode(L3);
	printNoHeadNode(L3);
	return 0;	
} 

如有错误,敬请指正!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值