目录
一、思维导图
二、作业
2.1 单向链表简单选择排序
2.2 单向链表按元素插入
2.3 单向链表按元素修改
三、双链表
3.1 双向链表结构体建立
3.2 双向链表节点创建
3.3 双向链表头插
3.4 双向链表尾插
3.5 双向链表头删
3.6 双向链表尾删
3.7 双向链表遍历
3.8 双链表全部代码
四、双向循环链表
4.1 双向循环链表结构体建立
4.2 双向循环链表节点创建
4.3 双向循环链表头插
4.4 双向循环链表尾插
4.5 双向循环链表头删
4.6 双向循环链表尾删
4.7 双向循环链表遍历
4.8 双向循环链表所有代码
/*
* function: 简单选择排序
* @param [ in]
* @param [out]
* @return
*/
void paixu(Linklist L)
{
//判断链表是否为空
//判断链表只有有一个节点
if( NULL==L || L->next==NULL )
{
return;
}
int i,j;
int len=Len_linklist(L);
Linklist p=L;
Linklist k=NULL;
for(i=0;inext)
{
if(q->data < p->data)
{
k=p;
}
}
if(k != q)
{
datatype t=k->data;k->data=q->data;q->data=t;
}
}
}
/*
* function: 按元素插入
* @param [ in]
* @param [out]
* @return
*/
Linklist insert_by_data(datatype key,datatype e,Linklist L)
{
int insert_pos=search_by_data(key,L);
if(insert_pos==-1)
return L;
L=insert_by_pos(insert_pos,e,L);
return L;
}
/*
* function: 按元素修改
* @param [ in]
* @param [out]
* @return
*/
Linklist modify_by_data(datatype key,datatype e,Linklist L)
{
int modify_pos=search_by_data(key,L);
if(modify_pos==-1)
return L;
L=modify_by_pos(modify_pos,e,L);
return L;
}
单向链表只可以向后遍历,使用起来不方便,那么引出双向链表,可以向前遍历。
typedef char datatype[20];
typedef struct Node
{
//数据域
datatype data;
//指针域:下一节点地址
struct Node *next;
//指针域:上一节点地址
struct Node *prev;
}*DouleLink;
/*
* function: 申请节点
* @param [ in]
* @param [out]
* @return
*/
DouleLink create_node()
{
DouleLink node=(DouleLink)malloc(sizeof(struct Node));
if(NULL==node)
{
return NULL;
}
strcpy(node->data,"");
node->next=node->prev=NULL;
return node;
}
/*
* function: 头插
* @param [ in]
* @param [out]
* @return
*/
DouleLink insert_head(datatype e,DouleLink L)
{
//1.创建新节点
DouleLink s=create_node();
if(NULL==s)
return L;
//
strcpy(s->data,e);
if(NULL!=L)
{
s->next=L;
L->prev=s;
}
L=s;
return L;
}
/*
* function: 尾插
* @param [ in]
* @param [out]
* @return
*/
DouleLink insert_rear(datatype e,DouleLink L)
{
//1.创建新节点
DouleLink s=create_node();
if(NULL==s)
return L;
strcpy(s->data,e);
//2.链表为空
if(NULL==L)
{
L=s;
return L;
}
//3.已有多个节点
//找到尾部节点
DouleLink rear=L;
while(rear->next!=NULL)
{
rear=rear->next;
}
rear->next=s;
s->prev=rear;
return L;
}
/*
* function: 头删
* @param [ in]
* @param [out]
* @return
*/
DouleLink delete_head(DouleLink L)
{
//1.如果链表为空
if(NULL==L)
return L;
//2.判断链表只有一个节点
if(NULL==L->next)
{
free(L);
L=NULL;
return L;
}
//3.有多个节点
DouleLink q=L->next;
strcpy(L->data,q->data);
L->next=q->next;
if(q->next!=NULL)
q->next->prev=L;
free(q);
q=NULL;
return L;
}
/*
* function: 头删
* @param [ in]
* @param [out]
* @return
*/
DouleLink delete_head(DouleLink L)
{
//1.如果链表为空
if(NULL==L)
return L;
//2.判断链表只有一个节点
if(NULL==L->next)
{
free(L);
L=NULL;
return L;
}
//3.有多个节点
DouleLink q=L->next;
strcpy(L->data,q->data);
L->next=q->next;
if(q->next!=NULL)
q->next->prev=L;
free(q);
q=NULL;
return L;
}
/*
* function: 循环输出
* @param [ in]
* @param [out]
* @return
*/
void output(DouleLink L)
{
//1.如果为空
if(NULL==L)
{
return;
}
//2.如果存在节点
//正向遍历
puts("正向遍历:");
while(L->next!=NULL)
{
printf("%s\t",L->data);
L=L->next;
}
printf("%s\n",L->data);
//逆向遍历
puts("逆向遍历:");
while(L!=NULL)
{
printf("%s\t",L->data);
L=L->prev;
}
puts("");
}
double_head.h
#ifndef __HEAD__H__
#define __HEAD__H__
#include
#include
#include
typedef char datatype[20];
typedef struct Node
{
//数据域
datatype data;
//指针域:下一节点地址
struct Node *next;
//指针域:上一节点地址
struct Node *prev;
}*DouleLink;
DouleLink insert_head(datatype e,DouleLink L);
void output(DouleLink L);
DouleLink insert_rear(datatype e,DouleLink L);
DouleLink delete_head(DouleLink L);
DouleLink delete_head(DouleLink L);
DouleLink delete_rear(DouleLink L);
#endif
double_main.c
#include "double_head.h"
int main(int argc, const char *argv[])
{
DouleLink L=NULL;
int n;
datatype e;
printf("please enter n:");
scanf("%d",&n);
for(int i=0;i
double_test.c
#include "double_head.h"
/*
* function: 申请节点
* @param [ in]
* @param [out]
* @return
*/
DouleLink create_node()
{
DouleLink node=(DouleLink)malloc(sizeof(struct Node));
if(NULL==node)
{
return NULL;
}
strcpy(node->data,"");
node->next=node->prev=NULL;
return node;
}
/*
* function: 头插
* @param [ in]
* @param [out]
* @return
*/
DouleLink insert_head(datatype e,DouleLink L)
{
//1.创建新节点
DouleLink s=create_node();
if(NULL==s)
return L;
//
strcpy(s->data,e);
if(NULL!=L)
{
s->next=L;
L->prev=s;
}
L=s;
return L;
}
/*
* function: 循环输出
* @param [ in]
* @param [out]
* @return
*/
void output(DouleLink L)
{
//1.如果为空
if(NULL==L)
{
return;
}
//2.如果存在节点
//正向遍历
puts("正向遍历:");
while(L->next!=NULL)
{
printf("%s\t",L->data);
L=L->next;
}
printf("%s\n",L->data);
//逆向遍历
puts("逆向遍历:");
while(L!=NULL)
{
printf("%s\t",L->data);
L=L->prev;
}
puts("");
}
/*
* function: 尾插
* @param [ in]
* @param [out]
* @return
*/
DouleLink insert_rear(datatype e,DouleLink L)
{
//1.创建新节点
DouleLink s=create_node();
if(NULL==s)
return L;
strcpy(s->data,e);
//2.链表为空
if(NULL==L)
{
L=s;
return L;
}
//3.已有多个节点
//找到尾部节点
DouleLink rear=L;
while(rear->next!=NULL)
{
rear=rear->next;
}
rear->next=s;
s->prev=rear;
return L;
}
/*
* function: 头删
* @param [ in]
* @param [out]
* @return
*/
DouleLink delete_head(DouleLink L)
{
//1.如果链表为空
if(NULL==L)
return L;
//2.判断链表只有一个节点
if(NULL==L->next)
{
free(L);
L=NULL;
return L;
}
//3.有多个节点
DouleLink q=L->next;
strcpy(L->data,q->data);
L->next=q->next;
if(q->next!=NULL)
q->next->prev=L;
free(q);
q=NULL;
return L;
}
/*
* function: 尾删
* @param [ in]
* @param [out]
* @return
*/
DouleLink delete_rear(DouleLink L)
{
//1.如果链表为空
if(NULL==L)
return L;
//2.判断链表只有一个节点
if(NULL==L->next)
{
free(L);
L=NULL;
return L;
}
//3.有多个节点
DouleLink rear=L;
while(rear->next!=NULL)
rear=rear->next;
rear->prev->next=NULL;
free(rear);
rear=NULL;
return L;
}
因为双向链表在找尾节点是,需要从第一个节点遍历到最后一个节点,时间复杂度高,而且单链表只能向后遍历,不可以向前,所以引出双向循环链表。双向循环链表最大特点是:不需要通过循环找到尾节点,相对方便。
typedef char datatype[20];
typedef struct Node
{
//数据域
datatype data;
//指针域
struct Node *next;
//指针域
struct Node *prev;
}*DouleLink;
/*
* function: 申请节点
* @param [ in]
* @param [out]
* @return
*/
DouleLink create_node()
{
DouleLink node=(DouleLink)malloc(sizeof(struct Node));
if(NULL==node)
{
return NULL;
}
strcpy(node->data,"");
node->next=node->prev=NULL;
return node;
}
/*
* function: 头插
* @param [ in]
* @param [out]
* @return
*/
DouleLink insert_head(datatype e,DouleLink L)
{
//1.创建新节点
DouleLink s=create_node();
if(NULL==s)
return L;
//
strcpy(s->data,e);
if(NULL!=L)
{
s->next=L;
L->prev=s;
}
L=s;
return L;
}
/*
* function: 尾插
* @param [ in]
* @param [out]
* @return
*/
DouleLink insert_rear(datatype e,DouleLink L)
{
//1.创建新节点
DouleLink s=create_node();
if(NULL==s)
return L;
strcpy(s->data,e);
//2.链表为空
if(NULL==L)
{
L=s;
return L;
}
//3.已有多个节点
//找到尾部节点
DouleLink rear=L;
while(rear->next!=NULL)
{
rear=rear->next;
}
rear->next=s;
s->prev=rear;
return L;
}
/*
* function: 头删
* @param [ in]
* @param [out]
* @return
*/
DouleLink delete_head(DouleLink L)
{
//1.如果链表为空
if(NULL==L)
return L;
//2.判断链表只有一个节点
if(NULL==L->next)
{
free(L);
L=NULL;
return L;
}
//3.有多个节点
DouleLink q=L->next;
strcpy(L->data,q->data);
L->next=q->next;
if(q->next!=NULL)
q->next->prev=L;
free(q);
q=NULL;
return L;
}
/*
* function: 尾删
* @param [ in]
* @param [out]
* @return
*/
DouleLink delete_rear(DouleLink L)
{
//1.如果链表为空
if(NULL==L)
return L;
//2.判断链表只有一个节点
if(NULL==L->next)
{
free(L);
L=NULL;
return L;
}
//3.有多个节点
DouleLink rear=L;
while(rear->next!=NULL)
rear=rear->next;
rear->prev->next=NULL;
free(rear);
rear=NULL;
return L;
}
/*
* function: 循环输出
* @param [ in]
* @param [out]
* @return
*/
void output(DouleLink L)
{
//1.如果为空
if(NULL==L)
{
return;
}
//2.如果存在节点
//正向遍历
puts("正向遍历:");
while(L->next!=NULL)
{
printf("%s\t",L->data);
L=L->next;
}
printf("%s\n",L->data);
//逆向遍历
puts("逆向遍历:");
while(L!=NULL)
{
printf("%s\t",L->data);
L=L->prev;
}
puts("");
}
head.h
#ifndef __HEAD__H__
#define __HEAD__H__
#include
#include
#include
typedef char datatype[20];
typedef struct Node
{
//数据域
datatype data;
//指针域
struct Node *next;
//指针域
struct Node *prev;
}*DouleLink;
DouleLink insert_head(datatype e,DouleLink L);
void output(DouleLink L);
DouleLink insert_rear(datatype e,DouleLink L);
DouleLink delete_head(DouleLink L);
DouleLink delete_head(DouleLink L);
DouleLink delete_rear(DouleLink L);
#endif
main.c
#include "double_head.h"
int main(int argc, const char *argv[])
{
DouleLink L=NULL;
int n;
datatype e;
printf("please enter n:");
scanf("%d",&n);
for(int i=0;i
test.c
#include "double_head.h"
/*
* function: 申请节点
* @param [ in]
* @param [out]
* @return
*/
DouleLink create_node()
{
DouleLink node=(DouleLink)malloc(sizeof(struct Node));
if(NULL==node)
{
return NULL;
}
strcpy(node->data,"");
node->next=node->prev=NULL;
return node;
}
/*
* function: 头插
* @param [ in]
* @param [out]
* @return
*/
DouleLink insert_head(datatype e,DouleLink L)
{
//1.创建新节点
DouleLink s=create_node();
if(NULL==s)
return L;
//
strcpy(s->data,e);
if(NULL!=L)
{
s->next=L;
L->prev=s;
}
L=s;
return L;
}
/*
* function: 循环输出
* @param [ in]
* @param [out]
* @return
*/
void output(DouleLink L)
{
//1.如果为空
if(NULL==L)
{
return;
}
//2.如果存在节点
//正向遍历
puts("正向遍历:");
while(L->next!=NULL)
{
printf("%s\t",L->data);
L=L->next;
}
printf("%s\n",L->data);
//逆向遍历
puts("逆向遍历:");
while(L!=NULL)
{
printf("%s\t",L->data);
L=L->prev;
}
puts("");
}
/*
* function: 尾插
* @param [ in]
* @param [out]
* @return
*/
DouleLink insert_rear(datatype e,DouleLink L)
{
//1.创建新节点
DouleLink s=create_node();
if(NULL==s)
return L;
strcpy(s->data,e);
//2.链表为空
if(NULL==L)
{
L=s;
return L;
}
//3.已有多个节点
//找到尾部节点
DouleLink rear=L;
while(rear->next!=NULL)
{
rear=rear->next;
}
rear->next=s;
s->prev=rear;
return L;
}
/*
* function: 头删
* @param [ in]
* @param [out]
* @return
*/
DouleLink delete_head(DouleLink L)
{
//1.如果链表为空
if(NULL==L)
return L;
//2.判断链表只有一个节点
if(NULL==L->next)
{
free(L);
L=NULL;
return L;
}
//3.有多个节点
DouleLink q=L->next;
strcpy(L->data,q->data);
L->next=q->next;
if(q->next!=NULL)
q->next->prev=L;
free(q);
q=NULL;
return L;
}
/*
* function: 尾删
* @param [ in]
* @param [out]
* @return
*/
DouleLink delete_rear(DouleLink L)
{
//1.如果链表为空
if(NULL==L)
return L;
//2.判断链表只有一个节点
if(NULL==L->next)
{
free(L);
L=NULL;
return L;
}
//3.有多个节点
DouleLink rear=L;
while(rear->next!=NULL)
rear=rear->next;
rear->prev->next=NULL;
free(rear);
rear=NULL;
return L;
}