一、双链表
在单链表的基础上再增加一个指向它前驱的指针,就构成了双链表。
所以双链表有三个变量:数据信息info、前驱指针llink、后继指针rlink。
二、双链表操作和实现
由于双链表也为单链表的一种变型,一些相似的操作就没一一列举,可以参考数据结构(四)——单链表 、带头结点的单链表、循环链表 及其实现
1、数据结构
2、在i位置插入结点
3、在y元素后插入结点
4、删除值为x的结点
1、数据结构
[cpp] view plain ?
- typedef int datatype;
- typedef struct dlink_node{
- datatype info;
- dlink_node* llink;
- dlink_node* rlink;
- }dnode;
2、在i位置插入结点[cpp] view plain ?
- include"linklist.h"
- node* insert_link_list_index(node *head,int index,datatype x){
- if(index<0){
- printf("index error\n");
- exit(1);
- }
- if(index == 0){ //在链表首插入
- node *q = (node*) malloc(sizeof(node));
- q->info = x;
- if(!head){ //空表的情况
- q->llink = NULL;
- q->rlink = NULL;
- head = q;
- return head;
- }
- head->llink = q; //非空链表首插入
- q->rlink = head;
- q->llink = NULL;
- head = q;
- return head;
- }
- else{
- node *ptr = find_node(head,index-1);
- node* q = (node*)malloc(sizeof(node));
- q->info = x;
- if(ptr->next){ //链表中插入
- p->rlink = ptr->rlink;
- ptr->rlink->llink = p;
- ptr->rlink = p;
- p->llink = ptr
- return head;
- }
- ptr->rlink = p; //链表尾插入
- p->llink = ptr;
- p->rlink = NULL;
- return head;
- }
- }
3、在y元素之后插入
[cpp] view plain ?
- #include"linklist.h"
- node* intsert_node_yx(node *head,datatype x,datatype y){
- node *q=find_node(head,y);
- if(!q){
- printf("not found the node %d\n");
- return head;
- }
- node *p = (node*)malloc(sizeof(node));
- p->info = x;
- if(!q->rlink){ //最后一个结点
- q->rlink = p;
- p->llink = q;
- p->rlink = NULL;
- return head;
- }
- p->rlink = q->rlink; //中间结点
- q->rlink->llink = p;
- q->rlink = p;
- p->llink = q;
- return head;
- }
4、删除值为x的结点[cpp] view plain ?
- #include"linklist.h"
- node* del_link_list_node(node* head,datatype x){
- if(!head){
- printf("the list is empty\n");
- return head;
- }
- node* ptr=head;
- while(!ptr && ptr->info != x){
- ptr=ptr->rlink;
- }
- if(!ptr){ //未找到数据
- printf("no data\n");
- }else if(ptr == head && ptr->rlink){ //第一个就是,还有后继
- head=ptr->rlink;
- ptr->rlink->llink = NULL; //因为这步所以要判断是否有后继
- }else if(ptr == head && !ptr->rlink){ //第一个就是,只有一个元素
- head = NULL;
- }
- }else if(!ptr->rlink){ //链表的最后一个
- ptr->llink->rlink = NULL;
- }else{
- ptr->llink->rlink = ptr->rlink; //链表中间
- ptr->rlink->llink = ptr->llink;
- }
- free(ptr);
- return head;
- }
三、链式栈
栈的链式存储称为链式栈。它的插入和删除规定在单链表的同一端进行,栈顶指针用top表示。
1、输出各个结点的值
2、取得栈顶元素
3、入栈
4、出栈
1、输出各个结点的值
[cpp] view plain ?
- #include"linklist.h"
- void display_link_list(node *stack){
- if(!stack){
- printf("the list is empty!\n");
- }else{
- int i;
- node *ptr = stack;
- while(ptr){
- printf("5%d",ptr->info);
- ptr = ptr->next;
- }
- }
- }
2、取得栈顶元素[cpp] view plain ?
- #include"linklist.h"
- node* get_top(node *stack){
- if(!stack){
- printf("the stack is empty\n");
- return stack;
- }
- return stack->info;
- }
3、入栈[cpp] view plain ?
- #include"linklist.h"
- node* push(node* stack,datatype x){
- node *p = (node*)malloc(sizeof(node));
- p->info = x;
- p->next = stack; //当stack为空时,则有p->next = NULL
- stack = p;
- return p;
- }
4、出栈
[cpp] view plain ?
- #include"linklist.h"
- node* pop(node *stack,datatype *x){
- if(!stack){
- printf("the stack is empty\n");
- return stack;
- }
- node *p = stack;
- stack=stack->next;
- *x = p->info;
- free(p);
- return stack;
- }
四、链式队列
以队列形式存储的链式队列,插入和删除在单链表的不同端进行,队首和队尾指针存在一个数据结构中。
1、结构定义
2、建立一个空队列
3、判断是否为空
4、取得首节点值
5、输出各个结点
6、入列
7、出列
1、结构定义
[cpp] view plain ?
- typedef int datatype;
- typedef struct link_queue_node{
- datatype info;
- struct link_queue_node* next;
- }node;
- typedef struct queue{
- node* front;
- node* rear;
- }queue;
2、建立一个空队列[cpp] view plain ?
- #include"linkqueue.h"
- queue* init_link_queue(){
- queue *q = (queue*) malloc(sizeof(queue));
- q->front = NULL;
- q->rear = NULL;
- return q;
- }
3、判断是否为空[cpp] view plain ?
- #include"linkqueue.h"
- int is_empty_link_queue(queue *q){
- return q->front? 0:1;
- }
4、取得首节点值
[cpp] view plain ?
- #include"linkqueue.h"
- datatype* get_head(queue *q){
- if(!q){
- printf("the queue is empty\n");
- exit(1);
- }
- return q->front->info;
- }
5、输出各个结点[cpp] view plain ?
- #include"linkqueue.h"
- void display_link_queue(queue *q){
- if(!q){
- printf("the queue is empty!\n");
- }else{
- node *p = q->front;
- while(p){
- printf("%5d",p->info);
- p=p->next;
- }
- }
- }
6、入列
[cpp] view plain ?
- #include"linkqueue.h"
- queue* en_list_queue(queue *q,datatype x){
- node* p = (node*)malloc(sizeof(node));
- p->info = x;
- p->next = NULL;
- if(!q->front){
- q->front = p;
- q->rear = p;
- }else{
- rear->next = p;
- rear = p;
- }
- return q;
- }
7、出列[cpp] view plain ?
- #include"linkqueue.h"
- queue* del_link_queue(queue *q,datatype *x){
- if(!q->front){
- printf("the queue is empty\n");
- return q;
- }
- node *p = q->front;
- if(q->front == q->rear){
- q->front=q->rear=NULL;
- }else{
- q->front = p->next;
- }
- *x = p->info;
- free(p);
- return q;
- }