链表练习

准备:

	// 链表的节点
	typedef struct Node
	{
		TYPE data;			// 数据域
		struct Node* next;	// 指针域,指向下一个节点
	}Node;
	
	// 创建节点
	Node* create_node(TYPE data)
	{
		Node* node = malloc(sizeof(Node));
		node->data = data;
		node->next = NULL;
		return node;
	}
	
	// 链表
	typedef struct List
	{
		Node* head;
		Node* tail;
	}List;
	
	// 创建链表
	List* create_list(void)
	{
		List* list = malloc(sizeof(List));
		list->head = NULL;
		list->tail = NULL;
	}
  1. 练习1:链表逆序,在原链表的基础上调整
		void reverse_list(List* list)
		{
			if(list->head == list->tail)
			return;

			Node* n1 = NULL;
			Node* n2 = list->head;
			list->tail = n2;
			
			while(n2)
			{
				Node* n3 = n2->next;
				n2->next = n1;
				n1 = n2;
				n2 = n3;
			}
			list->head = n1;
		}
  1. 练习2:显示链表的倒数第K个值
		Node* show_list_k(List* list,int k)
		{
			/*
			int len = size_list(list);
			if(k <= 0 || k > len)
				return NULL;
			Node* node = list->head;
			for(int i=0; i<len-k; i++)
			{
				node = node->next;
			}
			return node;
			*/
			if(0 >= k) return NULL;
			Node* n1 = list->head;
			for(int i=0; i<k-1; i++)
			{
				n1 = n1->next;
				if(NULL == n1)
					return NULL;
			}
			n1 = n1->next;
			Node* n2 = list->head;
			while(n1)
			{
				n2 = n2->next;
				n1 = n1->next;
			}
			return n2;
		}

  1. 练习3:合并两个有序链表,并依然保持有序
		Node* _merge_list(Node* n1,Node* n2)
		{
			/*
			if(NULL == n1) return n2;
			if(NULL == n2) return n1;
		
			if(n1->data < n2->data)
			{
				n1->next = _merge_list(n1->next,n2);
				return n1;
			}
			else
			{
				n2->next = _merge_list(n1,n2->next);
				return n2;
			}
			*/
		
		
		}
		
		List* merge_list(List* l1,List* l2)
		{
			/*
			List* list = create_list();
			list->head = _merge_list(l1->head,l2->head);
			list->tail = l1->tail->next?l2->tail:l1->tail;
			return list;
			*/
			List* list = create_list();
			Node *n1 = l1->head ,*n2 = l2->head;
			if(n1->data < n2->data)
			{
				list->head = list->tail = n1;
				n1 = n1->next;
			}
			else
			{
				list->head = list->tail = n2;
				n2 = n2->next;
			}
		
			while(n1&&n2)
			{
				if(n1->data < n2->data)
				{
					list->tail->next = n1;
					n1 = n1->next;
				}
				else
				{
					list->tail->next = n2;
					n2 = n2->next;
				}
				list->tail = list->tail->next;
			}
			if(n1)
			{
				list->tail->next = n1;
				list->tail = l1->tail;
			}
			else
			{
				list->tail->next = n2;
				list->tail = l2->tail;
			}
		
			return list;
		}
  1. 练习4:判断链表中是否有环
		bool is_ring(List* list)
		{
			Node* n1 = list->head;
			Node* n2 = n1->next;
		
			while(n2 && n2->next)
			{
				if(n1 == n2 || n1 == n2->next)
				{
					return true;
				}
				n1 = n1->next;
				n2 = n2->next->next;
			}
			return false;
		}

  1. 练习5:找出环形链表的入口
		Node* in_ring(List* list)
		{
			for(Node* i=list->head->next; i!=NULL; i=i->next)
			{
				for(Node* j=list->head; j!=i; j=j->next)
				{
					if(j == i->next)
					{
						return j;
					}
				}
			}
			return NULL;
		}
  1. 练习6:判断是否是Y型链表,如果是则返回入口
		Node* is_Ylist(List* l1,List* l2)
		{
			int len1 = size_list(l1);
			int len2 = size_list(l2);
			
			Node *n1 = l1->head , *n2 = l2->head;
			if(len1 < len2)
			{
				n1 = l2->head;
				n2 = l1->head;
			}
			
			int i = abs(len1-len2);
			while(i--)n1 = n1->next;
		
			while(n1 && n2)
			{
				if(n1 == n2)
					return n1;
				n1 = n1->next;
				n2 = n2->next;
			}
			return NULL;
		}
  1. 练习7:删除链表中的重复节点
		void del_repeat(List* list)
		{
			for(Node* i=list->head; NULL!=i->next; i=i->next)
			{
				for(Node* j=i; NULL!=j&&NULL!=j->next; j=j->next)
				{
					if(i->data == j->next->data)
					{
						Node* temp = j->next;
						j->next = temp->next;
						free(temp);
					}
				}
			}
		}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值