STL中要用到顺序结构
以双链表为例,了解基本的增删改查操作
#ifndef __CIRCLEBOTHWAYLINKEDLISTWITHHEAD_H__
#define __CIRCLEBOTHWAYLINKEDLISTWITHHEAD_H__
typedef int ElemType; //数据元素中数据的类型
typedef struct node //数据节点的类型
{
ElemType data; //数据域 --》存储数据
struct node *next; //指针域 --》保存逻辑上的下一个
struct node *prev; //保存逻辑上的上一个
}DNODE;
typedef struct List //头节点的类型
{
struct node * first; //指向第一个节点
struct node * last; //指向最后一个节点
int node_num; //保存数据节点的个数
}DLIST;
struct List* create_bothway_Circle_list(); //创建双向循环链表
void print_bothway_Circle_list(struct List *list); //打印双向循环链表
struct List * add_a_node(struct List * list, ElemType x, ElemType a); //增加节点
struct List * create_sort_bothway_Circle_list(); //排序创建链表
struct List * delete_all_node(struct List * list, ElemType x); //删除节点
struct List * update_node(struct List * list, ElemType x,ElemType a); //查找并修改节点
void destroy_list(struct List ** list); //销毁链表
#endif
#include "CircleBothwayLinkedListWithHead.h"
#include <stdio.h>
#include <stdlib.h>
/*
根据用户的输入顺序,创建一个双向循环链表,将新链表返回
并打印输出
*/
struct List * create_bothway_Circle_list()
{
//1.创建一个头结点,并初始化
struct List *list = malloc(sizeof(struct List));
list->first = NULL;
list->last = NULL;
list->node_num = 0;
ElemType d; //保存从键盘上获取的数据
struct node *pnew = NULL; //指向新创建的数据节点
while(1)
{
//2.从键盘上获取数据
scanf("%d", &d);
if(d == 0) //人为约定,输入0结束
{
break;
}
//3.并创建数据节点,把数据写入到新创建的数据节点中
pnew = malloc(sizeof(struct node));
pnew->data = d;
pnew->next = NULL;
pnew->prev = NULL;
//4.把新节点 添加到 双向链表中
if(list->first == NULL) //从无到有
{
list->first = pnew;
list->last = pnew;
}
else //从少到多
{
//尾插法
list->last->next = pnew;
pnew->prev = list->last;
list->last = pnew;
//头插法
//pnew->next = list->first;
//list->first->prev = pnew;
//list->first = pnew;
}
list->node_num ++;
}
//5.首尾相连
if(list->node_num != 0)
{
list->last->next = list->first;
list->first->prev = list->last;
}
//6.返回新创建的链表的头结点
return list;
}
//打印链表
void print_bothway_Circle_list(struct List *list)
{
if(list == NULL)
{
printf("list is NULL !\n");
return;
}
struct node * p = list->first; //正向
int n = list->node_num*2;
while(n--)
{
printf("%d ", p->data);
p = p->next;
}
putchar('\n');
printf("======================================\n");
p = list->last; //逆向
n = list->node_num*2;
while(n--)
{
printf("%d ", p->data);
p = p->prev;
}
putchar('\n');
printf("======================================\n");
}
/*
查找值为x的节点,在x的前面加入一个值为a的节点,
如果没有找到x,就把a添加到末尾,将新链表返回
*/
struct List * add_a_node(struct List * list, ElemType x, ElemType a)
{
//1.创建一个新的节点,保存a
struct node *pnew = malloc(sizeof(struct node));
pnew->data = a;
pnew->next = NULL;
pnew->prev = NULL;
//2.找到值为x的节点 遍历(定义一个遍历指针)
struct node * p = list->first; //遍历指针
int n = list->node_num;
while(n--)
{
if(p->data == x)
{
break;
}
p = p->next;
}
if(n != -1 )
{
//3.找到了 就把新节点a插入
if(p == list->first)
{
//头插
pnew->next = list->first;
list->first->prev = pnew;
list->first = pnew;
}
else
{
//中间插入,先赋值pnew的成员,再去修复前后的链接
pnew->next = p;
pnew->prev = p->prev;
p->prev->next = pnew;
p->prev = pnew;
}
}
else
{
//4.没有找到了 尾插法
if(list->first == NULL) //空链表
{
list->first = pnew;
list->last = pnew;
}
else
{
//尾插
list->last->next = pnew;
pnew->prev = list->last;
list->last = pnew;
}
}
list->node_num ++;
//5.首尾相连
if(list->node_num != 0)
{
list->last->next = list->first;
list->first->prev = list->last;
}
//6.将新链表返回
return list;
}
/*
创建一个有序的双向循环链表,将新链表返回
*/
struct List * create_sort_bothway_Circle_list()
{
//1.创建一个头结点,并初始化
struct List *list = malloc(sizeof(struct List));
list->first = NULL;
list->last = NULL;
list->node_num = 0;
ElemType d; //保存从键盘上获取的数据
struct node *pnew = NULL; //指向新创建的数据节点
while(1)
{
//2.从键盘上获取数据
scanf("%d", &d);
if(d == 0) //人为约定,输入0结束
{
break;
}
//3.创建数据节点,把数据写入到新创建的数据节点中
pnew = malloc(sizeof(struct node));
pnew->data = d;
pnew->next = NULL;
pnew->prev = NULL;
//4.把新节点 添加到 双向链表中
if(list->first == NULL) //从无到有
{
list->first = pnew;
list->last = pnew;
}
else //从少到多
{
/*
分情况讨论:
比第一个节点还要小,头插
比最后一个节点还要大,尾插
中间插入,找到第一个比它大的节点的前面进行插入
//中间插入,先赋值pnew成员,再去修复前后的链接
*/
struct node *p = list->first; //遍历指针
while(p)
{
if(p->data > pnew->data)
{
break;
}
p = p->next;
}
if(p == NULL) //没有找到,尾插
{
list->last->next = pnew;
pnew->prev = list->last;
list->last = pnew;
}
else //找到了
{
if(p == list->first) //第一个,头插
{
pnew->next = list->first;
list->first->prev = pnew;
list->first = pnew;
}
else //中间插入
{
//先赋值pnew成员,再去修复前后的链接
pnew->next = p;
pnew->prev = p->prev;
p->prev->next = pnew;
p->prev = pnew;
}
}
}
list->node_num ++;
}
//5.首尾相连
if(list->node_num != 0)
{
list->last->next = list->first;
list->first->prev = list->last;
}
//6.返回新创建的链表的头结点
return list;
}
/*
在链表中找到值为x的节点,将其全部删除
若没有找到 就不删除,将新链表返回
*/
struct List * delete_all_node(struct List * list, ElemType x)
{
//1.找到值为x的节点
struct node *p = list->first; //遍历指针
int n = list->node_num;
while(n--)
{
if(p->data == x)
{
//2.找到了,删除
/*
分情况讨论:
删除第一个节点
删除最后一个节点
删除中间节点
//删除中间节点,先把前后的链接修复,再去断开自身的链接
*/
list->node_num --;
if(p == list->first) //删除第一个节点
{
list->first = list->first->next;
if(list->first != NULL)
{
list->first->prev = NULL;
}
p->next = NULL;
p->prev = NULL;
free(p);
p = list->first;
if(list->first == NULL) //最后一个节点也被删除了
{
list->last = NULL;
}
}
else if(p == list->last) //删除最后一个节点
{
list->last = list->last->prev;
list->last->next = NULL;
p->prev = NULL;
free(p);
p = NULL;
}
else //删除中间节点
{
struct node * temp = p->next;
//先把前后的链接修复,再去断开自身的链接
p->prev->next = p->next;
p->next->prev = p->prev;
p->next = NULL;
p->prev = NULL;
free(p);
p = temp;
}
}
else
{
//3.没有找到,就继续往下找
p = p->next;
}
}
//4.首尾相连
if(list->node_num != 0 )
{
list->last->next = list->first;
list->first->prev = list->last;
}
//5.返回新链表的头结点
return list;
}
/*
在链表中查找值为x的节点,将所有值为x的节点修改成a
如果没有找到,则不修改, 将新链表返回
*/
struct List * update_node(struct List * list, ElemType x,ElemType a)
{
struct node * p = list->first; //遍历指针
int n = list->node_num;
while(n--)
{
if(p->data == x)
{
p->data = a;
}
p = p->next;
}
return list;
}
//销毁一条链表
void destroy_list(struct List ** list)
{
struct node * p = (*list)->first; //遍历指针
int n = (*list)->node_num;
while(n--)
{
(*list)->first = p->next;
if((*list)->first != NULL)
{
(*list)->first->prev = NULL;
}
p->next = NULL;
free(p);
p = (*list)->first;
}
(*list)->node_num = 0;
(*list)->last = NULL;
free(*list);
*list = NULL;
}