/*****************************************************
Funcion List:
实现带表头节点的双向链表的
头插,尾插,中间插,倒序,释放
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
/*
=================
定义链表数据结构
=================
*/
struct node
{
int num;
struct node * next;
struct node * prior;
};
typedef struct node Node;
typedef struct node * Link;
/*
===============
功能:设头结点
返回:void
===============
*/
void creat_link(Link * head)
{
(*head) = (Link)malloc(sizeof(Node)) ; //创建一个新的节点,返回其地址
if(NULL == (*head))
{
printf("malloc error!\n");
exit(-1);
}
(*head) -> next = *head;
(*head) -> prior = *head;
}
/*
=====================
功能:从头部插入结点
返回:void
=====================
*/
void insert_node_head(Link * head,Link new_node)
{
Link tmp = *head;
new_node->next = (*head)->next;
(*head)->next->prior = new_node;
new_node->prior = *head;
(*head)->next = new_node;
if((*head) -> prior == *head)
{
(*head)->prior = new_node;
}
}
/*
=====================
功能:从尾部插入结点
返回:void
=====================
*/
void insert_node_tail(Link * head,Link new_node)
{
Link tmp;
tmp = *head;
while(tmp->next != (*head)) // while(tmp != NULL)
{ // {
tmp = tmp-> next; // tmp = tmp-> next; 此时已经已经指向NULL
} // }
tmp -> next = new_node;
new_node -> next = *head;
new_node -> prior = tmp;
(*head) -> prior = new_node;
/* 更好的写法 */
//head->prior->next = newnode;
//newnode->prior = head->prior;
//newnode->next = head;
//head->prior = newnode;
}
void insert_node_mid(Link * head,Link new_node,int num) //插入节点
{
Link tmp = (*head)->next;
if(*head == (*head)->next)
{
printf("link is empty !\n");
return;
}
else
{
while(tmp -> num != num && tmp -> next != (*head)) //找到要插入的位置
{
tmp = tmp -> next;
}
if(tmp -> num == num) //判断这个位置是否为真的节点
{
new_node -> next = tmp -> next;
new_node -> prior = tmp ;
tmp -> next -> prior = new_node;
tmp ->next = new_node;
}
else
{
printf("no such node!\n");
}
}
}
void delete_node(Link * head,int num_delete)
{
Link tmp = (*head)->next;
Link p = NULL;
if((*head) == tmp)
{
printf("link is empty !\n");
return;
}
else
{
while(tmp -> num != num_delete && tmp -> next != NULL)
{
p = tmp; //需要一个指针用于跟踪
tmp = tmp -> next;
}
if(tmp -> num == num_delete) //找到这个位置
{
/*if( tmp == (*head)->next)
{
tmp -> next -> prior = (*head);
(*head) -> next = tmp -> next;
free(tmp);
}
else if(tmp -> next == (*head))
{
p -> next = (*head);
(*head) -> prior = p;
free(tmp);
}
else
{
tmp -> next -> prior = p;
p -> next = tmp -> next;
free(tmp);
}*/
tmp->prior->next = tmp->next;
tmp->next->prior = tmp->prior;
free(tmp); //释放
tmp = NULL; //置空
}
else
{
printf("no such node!\n");
}
}
}
void revers_link(Link * head)
{
Link p1,p2,p3;
Link tmp = (*head)->next;
if((*head) -> next == (*head)) return;
else if((*head) -> next -> next == (*head))
{
(*head) -> next = tmp -> next;
tmp -> next -> next= tmp;
tmp -> next = (*head);
return;
}
else
{
p3 = tmp;
p2 = p3 -> next;
p1 = p2 -> next;
while(p1 -> next != (*head))
{
p2 -> next = p3;
p2 -> prior = p1;
p3 = p2;
p2 = p1;
p1 = p1->next;
}
p2 -> next = p3;
p2 -> prior = p1;
p1 -> next = p2;
p1 -> prior = (*head);
(*head) -> next -> next = (*head);
(*head) -> next = p1;
}
}
void free_node(Link * head)
{
Link tmp = (*head)->next;
Link p = *head;
if( tmp == (*head))
{
printf("link is emtpy\n");
return;
}
while( (*head)->next != (*head))
{
tmp = (*head)->next;
(*head) ->next = tmp -> next;
(*head) ->next -> prior = (*head);
free(tmp);
}
/*仍然需要构成环*/
(*head) -> next = (*head);
(*head) -> prior = (*head);
printf("Link is freed\n");
}
void display(Link head)
{
Link tmp;
tmp = head -> next;
if(head == head -> next)
{
printf("Link is empty\n");
}
while(tmp != head)
{
printf("num = %d\n",tmp->num);
tmp = tmp -> next;
}
}
int main()
{
Link head = NULL;
Link new_node = NULL;
int i;
int num_insert,num_delete;
creat_link(&head); //创建用于指向表头结点的Link型指针(头指针),此时指向NULL。
for(i = 0; i <10; i++)
{
new_node = (Link)malloc(sizeof(Node)) ; //创建一个新的节点,返回其地址
if(NULL == new_node)
{
printf("malloc error!\n");
exit(-1);
}
new_node -> num = i; //节点赋值
insert_node_head(&head,new_node); //插入节点
// insert_node(&head,new_node,new_node->num);
// insert_node_tail(&head,new_node); //插入节点(尾插)
}
display(head);
printf("请输入要插入的序号:");
scanf("%d",&num_insert);
new_node = (Link)malloc(sizeof(Node)) ; //创建一个新的节点,返回其地址
if(NULL == new_node)
{
printf("malloc error!\n");
exit(-1);
}
new_node -> num = 321; //节点赋值
insert_node_mid(&head,new_node,num_insert); //插入节点(中间)
display(head);
printf("请输入要删除的序号:");
scanf("%d",&num_delete);
delete_node(&head,num_delete);
display(head);
printf("------------\n");
revers_link(&head);
display(head);
printf("------------\n");
free_node(&head);
printf("------------\n");
display(head);
printf("------------\n");
return 0;
}
Funcion List:
实现带表头节点的双向链表的
头插,尾插,中间插,倒序,释放
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
/*
=================
定义链表数据结构
=================
*/
struct node
{
int num;
struct node * next;
struct node * prior;
};
typedef struct node Node;
typedef struct node * Link;
/*
===============
功能:设头结点
返回:void
===============
*/
void creat_link(Link * head)
{
(*head) = (Link)malloc(sizeof(Node)) ; //创建一个新的节点,返回其地址
if(NULL == (*head))
{
printf("malloc error!\n");
exit(-1);
}
(*head) -> next = *head;
(*head) -> prior = *head;
}
/*
=====================
功能:从头部插入结点
返回:void
=====================
*/
void insert_node_head(Link * head,Link new_node)
{
Link tmp = *head;
new_node->next = (*head)->next;
(*head)->next->prior = new_node;
new_node->prior = *head;
(*head)->next = new_node;
if((*head) -> prior == *head)
{
(*head)->prior = new_node;
}
}
/*
=====================
功能:从尾部插入结点
返回:void
=====================
*/
void insert_node_tail(Link * head,Link new_node)
{
Link tmp;
tmp = *head;
while(tmp->next != (*head)) // while(tmp != NULL)
{ // {
tmp = tmp-> next; // tmp = tmp-> next; 此时已经已经指向NULL
} // }
tmp -> next = new_node;
new_node -> next = *head;
new_node -> prior = tmp;
(*head) -> prior = new_node;
/* 更好的写法 */
//head->prior->next = newnode;
//newnode->prior = head->prior;
//newnode->next = head;
//head->prior = newnode;
}
void insert_node_mid(Link * head,Link new_node,int num) //插入节点
{
Link tmp = (*head)->next;
if(*head == (*head)->next)
{
printf("link is empty !\n");
return;
}
else
{
while(tmp -> num != num && tmp -> next != (*head)) //找到要插入的位置
{
tmp = tmp -> next;
}
if(tmp -> num == num) //判断这个位置是否为真的节点
{
new_node -> next = tmp -> next;
new_node -> prior = tmp ;
tmp -> next -> prior = new_node;
tmp ->next = new_node;
}
else
{
printf("no such node!\n");
}
}
}
void delete_node(Link * head,int num_delete)
{
Link tmp = (*head)->next;
Link p = NULL;
if((*head) == tmp)
{
printf("link is empty !\n");
return;
}
else
{
while(tmp -> num != num_delete && tmp -> next != NULL)
{
p = tmp; //需要一个指针用于跟踪
tmp = tmp -> next;
}
if(tmp -> num == num_delete) //找到这个位置
{
/*if( tmp == (*head)->next)
{
tmp -> next -> prior = (*head);
(*head) -> next = tmp -> next;
free(tmp);
}
else if(tmp -> next == (*head))
{
p -> next = (*head);
(*head) -> prior = p;
free(tmp);
}
else
{
tmp -> next -> prior = p;
p -> next = tmp -> next;
free(tmp);
}*/
tmp->prior->next = tmp->next;
tmp->next->prior = tmp->prior;
free(tmp); //释放
tmp = NULL; //置空
}
else
{
printf("no such node!\n");
}
}
}
void revers_link(Link * head)
{
Link p1,p2,p3;
Link tmp = (*head)->next;
if((*head) -> next == (*head)) return;
else if((*head) -> next -> next == (*head))
{
(*head) -> next = tmp -> next;
tmp -> next -> next= tmp;
tmp -> next = (*head);
return;
}
else
{
p3 = tmp;
p2 = p3 -> next;
p1 = p2 -> next;
while(p1 -> next != (*head))
{
p2 -> next = p3;
p2 -> prior = p1;
p3 = p2;
p2 = p1;
p1 = p1->next;
}
p2 -> next = p3;
p2 -> prior = p1;
p1 -> next = p2;
p1 -> prior = (*head);
(*head) -> next -> next = (*head);
(*head) -> next = p1;
}
}
void free_node(Link * head)
{
Link tmp = (*head)->next;
Link p = *head;
if( tmp == (*head))
{
printf("link is emtpy\n");
return;
}
while( (*head)->next != (*head))
{
tmp = (*head)->next;
(*head) ->next = tmp -> next;
(*head) ->next -> prior = (*head);
free(tmp);
}
/*仍然需要构成环*/
(*head) -> next = (*head);
(*head) -> prior = (*head);
printf("Link is freed\n");
}
void display(Link head)
{
Link tmp;
tmp = head -> next;
if(head == head -> next)
{
printf("Link is empty\n");
}
while(tmp != head)
{
printf("num = %d\n",tmp->num);
tmp = tmp -> next;
}
}
int main()
{
Link head = NULL;
Link new_node = NULL;
int i;
int num_insert,num_delete;
creat_link(&head); //创建用于指向表头结点的Link型指针(头指针),此时指向NULL。
for(i = 0; i <10; i++)
{
new_node = (Link)malloc(sizeof(Node)) ; //创建一个新的节点,返回其地址
if(NULL == new_node)
{
printf("malloc error!\n");
exit(-1);
}
new_node -> num = i; //节点赋值
insert_node_head(&head,new_node); //插入节点
// insert_node(&head,new_node,new_node->num);
// insert_node_tail(&head,new_node); //插入节点(尾插)
}
display(head);
printf("请输入要插入的序号:");
scanf("%d",&num_insert);
new_node = (Link)malloc(sizeof(Node)) ; //创建一个新的节点,返回其地址
if(NULL == new_node)
{
printf("malloc error!\n");
exit(-1);
}
new_node -> num = 321; //节点赋值
insert_node_mid(&head,new_node,num_insert); //插入节点(中间)
display(head);
printf("请输入要删除的序号:");
scanf("%d",&num_delete);
delete_node(&head,num_delete);
display(head);
printf("------------\n");
revers_link(&head);
display(head);
printf("------------\n");
free_node(&head);
printf("------------\n");
display(head);
printf("------------\n");
return 0;
}