单链表的基本操作:
--- 包括插入,删除,遍历等,最后有一个非递减链表的合并。
--- 注:使用的结构是带头节点的链表;
插入时:头插法的时间复杂度小于尾插,注意勾连顺序。
删除时:注意双指针的移动,头删时头相当于另一个指针。
将表置空时:需要特别注意的是将head - next置空。
#include <stdio.h>
#include <stdlib.h>
#define Elemtype int
/*-----------单链表结构------------*/
typedef struct node {
Elemtype data;
struct node* next;
}Node;
/*---------初始化为有头单链表-------------*/
Node* init_Link_list()
{
Node * head = (Node*)malloc(sizeof(Node));
if (NULL == head) {
printf("init error\n");
exit(-1);
}
head->next = NULL;
return head;
}
/*-------------创建节点-----------------*/
Node* create_Node()
{
Node *p= NULL;
while (p == NULL)
{
p = (Node*)malloc(sizeof(Node));
}
p->next = NULL;
return p;
}
/*-------------头插-------------------*/
void insert_H_list(Node* head,Elemtype val)
{
if (head == NULL) {
printf("list error\n");
return;
}
Node* New = create_Node();
New->data = val;
New->next = head->next;/*勾链*/
head->next = New;
}
/*-----------------获取尾节点-------------*/
Node* get_T_list(Node* head)
{
Node* p = head;
while (p->next != NULL)
p = p->next;
return p;
}
/*---------------尾插------------------*/
void insert_T_list(Node* head, Elemtype val)
{
if (head == NULL) {
printf("head is empty\n");
return;
}
Node* New = create_Node();
New->data = val;
Node* p = get_T_list(head);
/*------勾链-------*/
p->next = New;
/* New的指针在创建的时候最好置空
防止野指针的出现 */
}
/*-------------遍历-----------------------*/
void print_list(Node* head)
{
if (head->next == NULL) {
printf("list is empty\n");
return;
}
Node* p = head->next;
/*开始遍历,此处遍历可以传入一个函数指针,程序会更加灵活*/
while (p!=NULL)
{
printf("%3d", p->data);
p = p->next;
}
printf("\n");
}
/*---------------将表置空-------------*/
void set_Empty(Node* head)
{
if (head != NULL)
{
Node* p = head;
/*---------清空--------*/
while (head->next != NULL)
{
p = head->next;
head->next = p->next;
free(p);
}
head->next;/*注意将头置空*/
}
}
/*---------------尾删除------------------*/
void dele_T_list(Node* head)
{
if (head == NULL)
{
return;
}
/*单链表的删除:
除了头删法都要用到双指针
(这个缺陷可以用双向链表弥补)
*/
Node* p = head;
Node* d = p->next;
while (d->next != NULL)
{
/*在不删除时双指针步调不分先后*/
d = d->next;
p = p->next;
}
p->next = NULL;
free(d);
}
/*----------------查找定位删除--------------*/
void delete_val_list(Node* head, Elemtype val)
{
if (head == NULL)
{
printf("NO val :%d\n", val);
return;
}
Node* p = head;
Node* d= head->next;
while (d != NULL)
{
if (val == d->data)
{/*------删除-----*/
p->next = d->next;
free(d);d = NULL;
return; /*全删除时在此处更改,继续删除*/
}
p = p->next;
d = d->next;
}
/*-----当链表中不存在val时*--*/
printf("NO val :%d\n", val);
}
/*---------------两个非递减的链表合并---------*/
void marge_list(Node* La, Node* Lb, Node* Lc)
{
Node* pa = La->next;
Node* pb = Lb->next;
Node* pc = Lc;
while (pa != NULL&&pb != NULL)
{
if (pa->data <= pb->data) {
pc->next = pa;/*挂链*/
pa = pa->next;/*pa后移*/
pc = pc->next;/*更新pc*/
}
else {
pc->next = pb;/*挂链*/
pb = pb->next;/*pa后移*/
pc = pc->next;/*更新pc*/
}
}
/*将剩余节点挂链*/
while(pa != NULL) {
pc->next = pa;/*挂链*/
pa = pa->next;/*pa后移*/
pc = pc->next;/*更新pc*/
}
while (pb != NULL) {
pc->next = pb;/*挂链*/
pb = pb->next;/*pa后移*/
pc = pc->next;/*更新pc*/
}
}
int main()
{
//Node* head = init_Link_list();
/*for (int i = 1;i < 8;i++)
{
insert_H_list(head, i);
}
/*print_list(head);*/
/*for (int i = 0;i < 8;i++)
{
insert_T_list(head, i);
}
print_list(head);*/
/*delete_val_list(head, 3);
print_list(head);*/
/*dele_T_list(head);
print_list(head);
*/
/*print_list(head);
set_Empty( head);
print_list(head);
printf("haha\n");
*/
/*初始化三个链表*/
Node* La = init_Link_list();
Node* Lb = init_Link_list();
Node* Lc = init_Link_list();
print_list(Lc);
/*构造两个链表*/
insert_T_list(La, 4);
insert_T_list(La, 5);
insert_T_list(La, 9);
insert_T_list(La, 14);
print_list(La);
insert_T_list(Lb, 2);
insert_T_list(Lb, 8);
insert_T_list(Lb, 9);
insert_T_list(Lb, 14);
insert_T_list(Lb, 15);
print_list(Lb);
/*合成*/
marge_list(La, Lb, Lc);
print_list(Lc);
/*释放空间*/
//set_Empty(La);
print_list(La);
free(La);
set_Empty(Lb);
print_list(Lb);
free(Lb);
//set_Empty(Lc);
print_list(Lc);
free(Lc);
//set_Empty(head);
//print_list(head);
//free(head);
printf("haha\n");
system("pause");
return 0;
}
最后:将两个表合成后释放空间时的问题: 因为合并两个表时只是改变指针的指向,没有重新分配空间。 所以不能同时置空三个表,会造成空间的重复free.但是他们的 头节点还是要释放的。