链表的建立,搜索,插入,反转,销毁以及合并有序链表。

-创建,插入,反转链表-

​
/*关于链表的一系列操作*/ 
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
		int data;
		struct node *next;
	}Node,*linklist;

int main(){
	//创建链表,赋值 (头插法) 
	linklist head = (linklist)malloc(sizeof(Node));//head 头结点 
	linklist p = (linklist )malloc(sizeof(linklist ));//p 工具节点 
	head -> next = NULL;
	int n;
	printf ("输入要建立的链表长度:\n");
	scanf ("%d", &n);
	printf ("要输入的数字们:\n");
	while((n--) > 0){
		linklist p = (linklist )malloc(sizeof(linklist ));
		scanf("%d", &p -> data);
		p -> next = head -> next;
		head -> next = p;
	}
	//打印链表
	printf("\n生成的链表:\n");
	p = head -> next;
	while(p){
		printf("%-5d",p -> data);
		p = p -> next;
	}
	//在第n个位置插入数字 x
	
	printf("\n*接下来插入一个数字* \n\n要在第几个位置插入数字:\n");
	scanf("%d", &n);
	int x;
	printf("插入的数字:\n");
	scanf("%d", &x);
	p = head;
	linklist pre = (linklist )malloc(sizeof(linklist ));//pre 标记目标结点的前一个结点 
	n--;
	while(n!=0){
		p = p -> next;
		n--;
	}
	pre = p;
	linklist s = (linklist )malloc(sizeof(linklist ));//s 储存目标数字 
	s -> data = x;
	s -> next = pre -> next;
	pre -> next = s;
	//打印链表
	printf("\n插入后的新链表:\n");
	p = head -> next;
	while(p){
		printf("%-5d",p -> data);
		p = p -> next;
	}
	//三指针法反转这个链表
	pre = NULL;//指针1 
	linklist cur = (linklist )malloc(sizeof(linklist ));//指针2
	cur = head -> next;
	while(cur){
		linklist next = (linklist )malloc(sizeof(linklist ));//指针3
		next = cur -> next;
		cur -> next = pre;
		pre = cur;
		cur = next;
	}
	head -> next = pre;
	printf("\n\n反转链表 结果是:\n");
	//打印链表
	p = head -> next;
	while(p){
		printf("%-5d",p -> data);
		p = p -> next;
	}
}

​

        对于头插法和尾插法:链表尾插法是从链表头开始赋值,头插法则是从链表尾开始赋值。如对于一个长度为5的链表,输入1,2,3,4,5,尾插法打印出来的是1,2,3,4,5,头插法打印出来就是5,4,3,2,1。在建立时,头插法相对于尾插法可以少定义一个变量,个人觉得更方便一些。

        对于链表的查找与插入:找到目标结点的上一个结点再进行操作即可,注意使用一个指针来记录目标结点防止丢失链表。

        对于反转链表:这里使用三指针法反转链表。指针cur为操作指针,负责反转每个结点,指针pre记录前一结点,用于给操作指针定位。指针next记录后一结点,给操作指针引路(记录下一结点)。每次反转一个结点就让三个指针都后移一位。

        这里有个点要注意,就是控制循环终止的条件为while(cur)而不是while(pre)或while(next)。因为next总是先与cur一个结点,用next来控制会导致最后一个结点没有反转。

 -合并有序链表,及销毁-

#include <stdio.h>
#include <stdlib.h>
typedef struct node{
		int data;
		struct node *next;
	}Node,*linklist;

//尾插法创建链表 
void CreatTail(linklist head)
{
		Node *p,*s;
	p = head;
	int n;
	printf("要输入几个数字:\n"); 
	scanf("%d",&n);
	printf("输入你要输入的数字们 (从小到大):\n");
	while(n>0)
	{
		s = (Node *)malloc(sizeof(Node));
		scanf("%d",&s->data);
		s -> next = NULL;
		p -> next = s;
		p = s; 
		n--;
	}
	printf("\n");
}
int main(){
	//合并有序链表
	printf("\n\n*接下来合并有序链表*\n\n输入两个有序链表:\n"); 
	linklist head1 = (linklist)malloc(sizeof(Node));
	linklist head2 = (linklist)malloc(sizeof(Node));
	linklist head3 = (linklist)malloc(sizeof(Node));
	printf("\n*定义链表1*\n"); 
	CreatTail(head1); 
	printf("\n*定义链表2*\n"); 
	CreatTail(head2);
	linklist p1 = head1 -> next;
	linklist p2 = head2 -> next;
	linklist p3;
	if(p1 -> data < p2 -> data){
		head3 = p1;
		p1 = p1 -> next;
	}
	else{
		head3 = p2;
		p2 = p2 -> next;
	}
	p3 = head3;//此时head3直接指向第一个结点。 
	while(p1&&p2){
		if(p1 -> data <= p2 -> data){
			p3 -> next = p1;
			p3 = p1;
			p1 = p1 -> next;
		}
		else{
			p3 -> next = p2;
			p3 = p2;
			p2 = p2 -> next;
		}
	}
	if(p1!=NULL){
		p3 -> next = p1;
	}
	else{
		p2 -> next = p2;
	}
	
	//打印新链表
	printf("合成的新链表:\n"); 
	p = head3;
	while(p){
		printf("%-5d",p -> data);
		p = p -> next;
	}
	
	//销毁链表
	p = head3;
	linklist q = p;
	while(p)
	{
		p = p -> next;
		free(q);
		q = p;
	}
	head3 -> next = NULL;
}

        对于合并有序链表:基本思路就是另设一个头结点,再设两个标记指针p1和p2来遍历,引导合并待合并链表。当其中一个指针为空时,说明有一个链表已全部合并,说明另一个链表剩下的数都是更大的数,接下来让p指向另一个链表就行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值