single_linked_list.h
/*
**功能:应用C语言实现单链表的各项操作
** 1:建立节点
** 2:打印单链表
** 3:尾插
** 4:尾删
** 5:头插
** 6:头删
** 7:清空整个链表
** 8:获取链表长度
** 9:查找数据
** 10:在某位置后插入数据
** 11:删除某位置的数据
*//*
// 进阶应用
** 12:删除一个无头单链表的非尾节点
** 13:在无头单链表的一个非头节点前插入一个节点
** 14:查找中间节点
** 15:查找倒数第k个节点(要求只能遍历一次)
** 16:倒着打印单链表
** 17:逆置单链表
** 18:合并两个有序链表(合并后依然有序)
** 19:冒泡排序
**
*/
#ifndef __SINGLE_LINKED_LIST_
#define __SINGLE_LINKED_LIST_
typedef struct single_list
{
struct single_list* next;
DataType data;
}single_list_node;
/*
**功能:应用C语言实现单链表的各项操作
** 1:建立节点
** 2:打印单链表
** 3:尾插
** 4:尾删
** 5:头插
** 6:头删
** 7:清空整个链表
** 8:获取链表长度
** 9:查找数据
** 10:在某位置后插入数据
** 11:删除某位置的数据
*/
single_list_node* CreateSingleList(DataType data);
void destroySingleList(single_list_node* head);
single_list_node* SingleList_insertTail(single_list_node* head, DataType data);
single_list_node* SingleList_DeleteNodeTail(single_list_node* head);
single_list_node* SingleList_insertHead(single_list_node* head, DataType data);
single_list_node* SingleList_DeleteNodeHead(single_list_node* head);
single_list_node* singleList_insert_byPos(single_list_node* head, int pos, DataType data);
single_list_node* SingleList_NodeDelete_byPos(single_list_node* head,int pos);
single_list_node* SinleList_search_byData(single_list_node* head, DataType data);
single_list_node* SingleList_search_byPos(single_list_node* head, int pos);
void SingleList_showdata(single_list_node* head);
int Get_SingleList_Length(single_list_node* head);
void deleteListNode(single_list_node* node);
single_list_node* SingleList_BuyNode(DataType data);
single_list_node* SingleList_search_TailNode(single_list_node* head, single_list_node** tail_pre);
/*
// 进阶应用
** 12:删除一个无头单链表的非尾节点
** 13:在无头单链表的一个非头节点前插入一个节点
** 14:查找中间节点
** 15:查找倒数第k个节点(要求只能遍历一次)
** 16:倒着打印单链表
** 17:逆置单链表
** 18:合并两个有序链表(合并后依然有序)
** 19:冒泡排序
**
*/
/*15:查找倒数第k个节点(要求只能遍历一次)*/
single_list_node* find_Reverse_order_nth_number(single_list_node* head, int n);
/* 17:逆置单链表 */
single_list_node* Reverse_List(single_list_node* head);
/*合并两个有序链表*/
single_list_node* Merge_two_ordered_list(single_list_node* list1, single_list_node* list2);
/* 16:倒着打印单链表 */
void Reverse_print_linked_list(single_list_node* head);
/*链表排序*/
single_list_node* SortList(single_list_node* head);
/*查找中间节点*/
single_list_node* Find_middle_node(single_list_node* head);
#endif
sing_linked_list.c
#include "public.h"
#include "stack.h"
#include "single_linked_list.h"
/*创建链表,创建有一个节点的链表*/
single_list_node* CreateSingleList(DataType data)
{
single_list_node* node = NULL;
node = SingleList_BuyNode(data);
return node;
}
/*销毁整个链表*/
void destroySingleList(single_list_node* head)
{
single_list_node* next = NULL, *p = head;
while(NULL != p)
{
next = p->next;
deleteListNode(p);
p = next;
}
}
/*链表尾部插入节点*/
single_list_node* SingleList_insertTail(single_list_node* head, DataType data)
{
single_list_node *p = NULL, *tail = NULL;
single_list_node *new_node = NULL;
single_list_node* tail_pre = NULL;
new_node = SingleList_BuyNode(data);
p = SingleList_search_TailNode(head, &tail_pre);
if(NULL == p)
{
return new_node;
}
p->next = new_node;
return head;
}
/*尾部删除一个节点*/
single_list_node* SingleList_DeleteNodeTail(single_list_node* head)
{
single_list_node* p = head, *pre = NULL;
single_list_node* tail_pre = NULL;
if(NULL == head)
{
printf("head is NULL,no node can be deleted.\n");
return NULL;
}
p = SingleList_search_TailNode(head, &tail_pre);
if(head == p)
{
deleteListNode(p);
printf("delete head node when SingleList_DeleteNodeTail..\n");
return NULL;
}
deleteListNode(p);
tail_pre->next = NULL;
return head;
}
/*头插一个节点, 返回新的头结点*/
single_list_node* SingleList_insertHead(single_list_node* head, DataType data)
{
single_list_node *node = NULL, *p = head;
node = SingleList_BuyNode(data);
if(node == NULL)
{
printf("malloc Failed when SingleList_insertHead,so head not change.\n ");
return head;
}
node->next = head;
return node;
}
/*头删除一个节点*/
single_list_node* SingleList_DeleteNodeHead(single_list_node* head)
{
single_list_node* p = head, *head_next = NULL;
if(NULL == p)
{
printf("head is NULL when SingleList_DeleteNodeHead.\n ");
return NULL;
}
head_next = head->next;
deleteListNode(p);
return head_next;
}
/*指定位置后面插入一个节点,比如要插入1位置,则pos=0, 0位置插入不能用这个函数*/
single_list_node* singleList_insert_byPos(single_list_node* head, int pos, DataType data)
{
single_list_node* p = NULL, *new_node = NULL;
single_list_node* p_pos = NULL;
p_pos = SingleList_search_byPos(head, pos);
if(NULL != p_pos)
{
p = p_pos->next;
new_node = SingleList_BuyNode(data);
p_pos->next = new_node;
new_node->next = p;
}
else
{
printf("Not find the pos when singleList_insert_byPos.\n ");
return head;
}
return head;
}
/*删除指定位置的节点*/
single_list_node* SingleList_NodeDelete_byPos(single_list_node* head, int pos)
{
single_list_node* p_pos = NULL, *p = NULL;
single_list_node* pre = NULL;
p_pos = SingleList_search_byPos(head, pos);
if(NULL == p_pos)
{
printf("Not find pos in list when SingleList_NodeDelete_byPos.\n ");
return head;
}
//p指向删除节点的next
p = p_pos->next;
//删除的节点是0位置,头结点变化
if(head == p_pos)
{
deleteListNode(p_pos);
return p;
}
//找要删除节点的前驱
pre = head;
while(1)
{
if(pre->next == p_pos)
{
break;
}
pre = pre->next;
}
//删除节点的next指向删除节点的下一个节点
pre->next = p;
deleteListNode(p_pos);
return head;
}
/*指定位置查询*/
single_list_node* SingleList_search_byPos(single_list_node* head, int pos)
{
int i = 0;
single_list_node* p = head;
while(p != NULL)
{
if(i == pos)
{
return p;
}
++i;
p = p->next;
}
printf("List length is shorter than pos when SingleList_search_byPos.\n");
return NULL;
}
/*查找第一个数据是data的节点,并返回该节点指针*/
single_list_node* SinleList_search_byData(single_list_node* head, DataType data)
{
single_list_node* p = head;
while(NULL != p)
{
if(data == p->data)
{
return p;
}
p = p->next;
}
if(NULL == p)
{
printf("Single List not find the data:%d.\n", data);
return NULL;
}
return 0;
}
/*删除节点*/
void deleteListNode(single_list_node* node)
{
if(NULL != node)
{
free(node);
node = NULL;
}
}
/*malloc一个节点 并赋值*/
single_list_node* SingleList_BuyNode(DataType data)
{
single_list_node* node = (single_list_node*)malloc(sizeof(single_list_node));
node->data = data;
node->next = NULL;
return node;
}
/*显示数据*/
void SingleList_showdata(single_list_node* head)
{
single_list_node* p = head;
while(NULL != p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
printf("-------------------------------\n\n");
}
/*获取链表长度*/
int Get_SingleList_Length(single_list_node* head)
{
int len = 0;
single_list_node* p = head;
while(NULL != p)
{
++len;
p = p->next;
}
return len;
}
/*返回链表的尾部节点指针*/
single_list_node* SingleList_search_TailNode(single_list_node* head, single_list_node** tail_pre)
{
single_list_node* p = head;
*tail_pre = NULL;
if(NULL == p)
{
return NULL;
}
while(p->next != NULL)
{
*tail_pre = p;
p = p->next;
}
return p;
}
//
/*15:查找倒数第k个节点(要求只能遍历一次)*/
single_list_node* find_Reverse_order_nth_number(single_list_node* head, int n)
{
int i = 0;
single_list_node* p1 = head, *p2 = head;
if(n <=0)
{
printf("input %d is InValid.\n",n);
return NULL;
}
while(p1 != NULL)
{
++i;
if(i == n)
{
break;
}
p1 = p1->next;
}
if(i != n)
{
printf("The List's Length is less than n = %d\n", n);
return NULL;
}
while(p1->next != NULL)
{
p1 = p1->next;
p2 = p2->next;
}
return p2;
}
/* 16:倒着打印单链表 */
void Reverse_print_linked_list(single_list_node* head)
{
single_list_node* p = head;
stack* st = createStack();
while(p != NULL)
{
push(st, p->data );
p = p->next;
}
while(!StackIsEmpty(st))
{
printf("%d ",GetTop(st));
pop(st);
}
printf("\n");
}
/* 17:逆置单链表 */
single_list_node* Reverse_List(single_list_node* head)
{
single_list_node *p = NULL, *p_left = NULL, *p_right = NULL;
p_left = head ;
if(NULL == head)
{
return NULL;
}
/*p指向即将反转指向的节点,p_left指向被反转后的链表的尾部节点
p_right指向还没处理的部分的第一个节点*/
p = head->next;
p_left->next = NULL;
while(p != NULL)
{
p_right = p->next;
p->next = p_left;
p_left = p;
p = p_right;
}
return p_left;
}
/*链表排序:冒泡*/
single_list_node* SortList(single_list_node* head)
{
single_list_node *p = NULL, *p_left = NULL, *p_right = NULL;
single_list_node *tmp = NULL, *prev = NULL;
p_left = head;
if(head == NULL)
{
return NULL;
}
p = head->next;
p_left->next = NULL;
/*p_left指向已拍好序的链表的头结点
p_right指向还没排序的头节点
p是从未排序的链表的头部取下来,即将有序插入已排好序的p_left指向的链表*/
while(p != NULL)
{
p_right = p->next;
tmp = p_left;
/*tmp遍历已排好序的链表,找p的data应该放的位置
prev是最终p的前驱,tmp是p的后继*/
prev = NULL;
while(tmp != NULL && tmp->data < p->data)
{
prev = tmp;
tmp = tmp->next;
}
//比已排好序的链表的第一个元素还小,头插
if(NULL == prev)
{
p->next = p_left;
p_left = p;
p = p_right;
continue;
}
prev->next = p;
p->next = tmp;
p = p_right;
}
return p_left;
}
/*合并两个有序链表*/
/*思想:可以这样想,是将两个链表list1, list2合成一个第三个链表merge_list的过程。
1. 先从两个链表的头中选择小的节点,初始化作为合成链表merge_list的头,
2. 然后从两个链表头开始,选择两个链表头节点小的那一个,开始找,找到全部小于另外一个链表头的所有节点,
3. 将这部分加到merge_list,然后这个链表的头更新,
继续开始重复2, 直到有一个链表到达结尾null*/
single_list_node* Merge_two_ordered_list(single_list_node* list1, single_list_node* list2)
{
single_list_node *last1 = NULL, *p1 = NULL, *last2 = NULL, *p2 = NULL;
single_list_node *tmp1 = NULL, *tmp2 = NULL;
single_list_node* head = NULL;
if(NULL == list1)
{
return list2;
}
if(NULL == list2)
{
return list1;
}
p1 = list1;
p2 = list2;
/*两个链表都是从小到大的,因此两个头中小的那一个是合并后链表的头节点*/
if(p1->data <= p2->data)
{
head = p1;
}
else
{
head = p2;
}
/*两个指针p1 p2分别指向两个链表中本次在比较的数字,
举例子,假设p1->data <= p2->data情况:
选取小的那个节点所在的链表p1,从p1开始向后找,在list1中找到大于p2节点的前一个节点last1,
则p1到last1之间的数字都是小于p2节点的,将last1->next指向p2,即将list1中小于p2节点的节点从list1中插入到p2前面了。
此时p1更新为last1的下一个节点,开始新一次的处理*/
while(p1 != NULL && p2 != NULL)
{
if(p1->data <= p2->data)
{
tmp1 = p1;
while(tmp1 != NULL && tmp1->data <= p2->data)
{
last1 = tmp1;
tmp1 = tmp1->next;
}
last1->next = p2;
p1 = tmp1;
last1 = NULL;
}
else
{
tmp2 = p2;
while(tmp2 != NULL && tmp2->data <= p1->data)
{
last2 = tmp2;
tmp2 = tmp2->next;
}
last2->next = p1;
p2 = tmp2;
last2 = NULL;
}
}
return head;
}
/*查找中间节点*/
/*思想很简单,两个指针,同时开始从头走,一个一次走两步,一个一次走一步,
偶数节点时候,中间的返回前面或后面的都可,奇数个节点的时候返回中间节点*/
single_list_node* Find_middle_node(single_list_node* head)
{
single_list_node *p1 = NULL, *p2 = NULL;
if(NULL == head)
{
return NULL;
}
p1 = p2 = head;
while(p1 != NULL)
{
p1 = p1->next;
if(NULL == p1)
{
break;
}
p1 = p1->next;
p2 = p2->next;
}
return p2;
}