链表特点:1.插入和删除快(尾巴操作慢,尾巴插入可以增加尾指针使其变为O(1))
缺点:
1. 查找不方便
2. 数据密度小
3. 内存碎片
带头节点的单链表
#pragma once
//带头结点单链表:最后一个节点的next为NULL;带头结点操作简单
typedef struct Node
{
int data;//存放数据
struct Node *next;//存放下一个节点的地址
}Node,*List;//List == Node *
//typedef Node * List;//List == Node *
//初始化
void InitList(List plist);
//头插
void Insert_head(List plist,int val);
//尾插
void Insert_tail(List plist,int val);
//查找
Node *Search(List plist,int key);
//删除
bool DeleteVal(List plist,int key);
//获取数据节点总数,不包含头
int GetLength(List plist);
//判空
bool IsEmpty(List plist);
//清空
void Clear(List plist);
//摧毁
void Destroy(List plist);
//输出
void Show(List plist);
void Reverse(List plist);
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "list.h"
void InitList(List plist)
{
assert(plist!=NULL);
if(plist==NULL)
{
return;
}
plist->next=NULL;
}
void Insert_head(List plist,int val)
{
Node *p=(Node *)malloc(sizeof(Node));
p->data=val;
p->next=plist->next;
plist->next=p;
//Node newnode={val,NULL};//1
//newnode.next=plist->next;//3
//plist->next=&newnode;//2
}
void Insert_tail(List plist,int val)
{
Node *p;
for(p=plist;p->next!=NULL;p=p->next);
Node *q=(Node *)malloc(sizeof(Node));
q->data=val;
q->next=p->next;
p->next=q;
}
Node *Search(List plist,int key)
{
for(Node *p=plist->next;p!=NULL;p=p->next)
{
if(p->data==key)
{
return p;
}
}
return NULL;
}
bool DeleteVal(List plist,int key)
{
Node *p=Search(plist,key);
if(p==NULL)
{
return false;
}
Node *q=p->next;
p->next=q->next;
free(q);
return true;
}
int GetLength(List plist)
{
int count=0;
for(Node *p=plist->next;p!=NULL;p=p->next)
{
count++;
}
return count;
}
bool IsEmpty(List plist)
{
if(plist->next==NULL)
{
return true;
}
return false;
}
void Clear(List plist)
{
Destroy(plist);
}
void Destroy(List plist)
{
assert(plist!=NULL);
if(plist==NULL)
{
return;
}
Node *p;
while(plist->next!=NULL)
{
p=plist->next;
plist->next=p->next;
free(p);
}
/*
if(plist==NULL||plist->next==NULL)
{
return;
}
Node *p=plist->next;
Node *q;
plist->next=NULL;
while(p!=NULL)
{
q=p->next;
free(p);
p=q;
}
*/
}
void Show(List plist)
{
for(Node *p=plist->next;p!=NULL;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}
//考的最多
void Reverse(List plist)
{
//if(plist==NULL||plist->next->next==NULL||plist->next==NULL)//err
if(plist==NULL||plist->next==NULL||plist->next->next==NULL)
{
return ;
}
Node *p=plist->next;
Node *q;
plist->next=NULL;
while(p!=NULL)
{
q=p->next;
p->next=plist->next;
plist->next=p;
p=q;
}
}
#include <stdio.h>
#include "list.h"
int main()
{
Node head;
InitList(&head);
//for(int i=0;i<20;i++)
//{
//Insert_head(&head,i);
//}
//Show(&head);
for(int i=0;i<20;i++)
{
Insert_tail(&head,i);
}
Show(&head);
printf("%d\n",Search(&head,3));
printf("%d\n",Search(&head,0));
printf("%d\n",Search(&head,30));
printf("%d\n",GetLength(&head));
DeleteVal(&head,3);
Show(&head);
DeleteVal(&head,25);
Show(&head);
DeleteVal(&head,18);
Show(&head);
Reverse(&head);
Show(&head);
Destroy(&head);
Show(&head);
Clear(&head);
Show(&head);
return 0;
}
不带头结点的单链表
#pragma once
//不带头结点的单链表
typedef struct NNode
{
int data;
struct NNode *next;
}NNode,*NList;
void InitList(NList *pplist);
bool Insert_head(NList *pplist,int val);
bool Insert_tail(NList *pplist,int val);
bool Delete(NList *pplist,int key);
void Destroy(NList *pplist);
void Show(NList plist);
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//将带头节点的单链表改成不带头节点的单链表,并实现插入,删除,查找,求链表长度,
//打印等函数。
typedef struct NNode
{
int data;
struct NNode *next;
}NNode,*NList;
//初始化
void InitList(NList *pplist)
{
assert(pplist!=NULL);
if(pplist==NULL)
{
return ;
}
*pplist=NULL;
}
//头插
void Insert_head(NList *pplist,int val)
{
NNode *p=(NNode *)malloc(sizeof(NNode));
p->data=val;
p->next=*pplist;
*pplist=p;
}
//尾插
bool Insert_tail(NList *pplist,int val)
{
NNode *p=(NNode *)malloc(sizeof(NNode));
p->data=val;
p->next=NULL;
if(*pplist==NULL)
{
*pplist=p;
return true;
}
NNode *q;
for(q=*pplist;q->next!=NULL;q=q->next);
p->next=q->next;
q->next=p;
return true;
}
//查找
NNode *Search(NList plist,int key)
{
NNode *p;
for(p=plist->next;p!=NULL;p=p->next)
{
if(p->data==key)
{
return p;
}
}
return NULL;
}
//删除
bool DeleteVal(NList *pplist,int key)
{
if(*pplist==NULL)
{
return false;
}
NNode *p=*pplist;
if(p->data==key)
{
*pplist=p->next;
free(p);
return true;
}
for(p=*pplist;p->next!=NULL;p=p->next)
{
if(p->next->data==key)
{
NNode *q=p->next;
p->next=q->next;
free(q);
return true;
}
}
return false;
}
//获取数据节点总数,不包含头
int GetLength(NList plist)
{
int count=0;
for(NNode *p=plist->next;p!=NULL;p=p->next)
{
count++;
}
return count;
}
//判空
bool IsEmpty(NList plist)
{
return plist==NULL;
}
void Clear(NList *pplist)
{
Destroy(pplist);
}
void Destroy(NList *pplist)
{
NNode *p;
while(*pplist!=NULL)
{
p=*pplist;
*pplist=p->next;
free(p);
}
*pplist=NULL;
}
//输出
void Show(NList plist)
{
for(NNode *p=plist->next;p!=NULL;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}
#include <stdio.h>
#include "nlist.h"
int main()
{
NList head;
InitList(&head);
for(int i=0;i<20;i++)
{
Insert_head(&head,i);
}
Show(head);
for(int i=0;i<20;i++)
{
Insert_tail(&head,i);
}
Show(head);
printf("%d\n",Search(head,3));
printf("%d\n",Search(head,25));
DeleteVal(&head,3);
DeleteVal(&head,12);
DeleteVal(&head,-2);
Show(head);
Destroy(&head);
Show(head);
return 0;
}
带头结点的双向链表
#pragma once
//带头结点的双向链表,不循环
typedef struct DNode
{
int data;
struct DNode *prio;//前驱指针
struct DNode *next;//后继指针
}DNode,*DList;
//初始化
void InitList(DList plist);
//头插
void Insert_head(DList plist,int val);
//尾插
void Insert_tail(DList plist,int val);
//查找
DNode *Search(DList plist,int key);
//删除
bool DeleteVal(DList plist,int key);
//获取数据节点总数,不包含头
int GetLength(DList plist);
//判空
bool IsEmpty(DList plist);
//清空
void Clear(DList plist);
//摧毁
void Destroy(DList plist);
//输出
void Show(DList plist);
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "dlist.h"
//初始化
void InitList(DList plist)
{
assert(plist!=NULL);
if(plist==NULL)
{
return ;
}
plist->next=NULL;
plist->prio=NULL;
}
//头插
void Insert_head(DList plist,int val)
{
DNode *p=(DNode *)malloc(sizeof(DNode));
p->data=val;
p->next=plist->next;
plist->next=p;
p->prio=plist;
if(p->next!=NULL)
{
p->next->prio=p;
}
}
//尾插
void Insert_tail(DList plist,int val)
{
DNode *p;
for(p=plist;p->next!=NULL;p=p->next);
DNode *q=(DNode *)malloc(sizeof(DNode));
q->data=val;
q->next=p->next;
p->next=q;
q->prio=p;
if(q->next!=NULL)
{
q->next->prio=q;
}
}
//查找
DNode *Search(DList plist,int key)
{
for(DNode *p=plist->next;p!=NULL;p=p->next)
{
if(p->data==key)
{
return p;
}
}
return NULL;
}
//删除
bool DeleteVal(DList plist,int key)
{
DNode *p=Search(plist,key);
if(p==NULL)
{
return false;
}
p->prio->next=p->next;
if(p->next!=NULL)
{
p->next->prio=p->prio;
}
free(p);
return true;
}
//获取数据节点总数,不包含头
int GetLength(DList plist)
{
int count=0;
DNode *p;
for(p=plist->next;p!=NULL;p=p->next)
{
count++;
}
return count;
}
//判空
bool IsEmpty(DList plist)
{
return plist->next==NULL;
}
//清空
void Clear(DList plist)
{
Destroy(plist);
}
//摧毁
void Destroy(DList plist)
{
DNode *p;
while(plist->next!=NULL)
{
p=plist->next;
plist->next=p->next;
free(p);
}
}
//输出
void Show(DList plist)
{
DNode *p;
for(p=plist->next;p!=NULL;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}
#include <stdio.h>
#include "dlist.h"
int main()
{
DNode head;
InitList(&head);
for(int i=0;i<20;i++)
{
Insert_head(&head,i);
}
Show(&head);
for(int i=0;i<20;i++)
{
Insert_tail(&head,i);
}
Show(&head);
printf("%d\n",Search(&head,5));
printf("%d\n",Search(&head,-1));
printf("%d\n",Search(&head,25));
DeleteVal(&head,3);
Show(&head);
printf("%d\n",GetLength(&head));
return 0;
}
带头结点的循环链表
#pragma once
//带头结点的循环链表:尾节点的next指向头结点
typedef struct CNode
{
int data;
struct CNode *next;
}CNode,*CList;
//初始化
void InitList(CList plist);
//头插
void Insert_head(CList plist,int val);
//尾插
void Insert_tail(CList plist,int val);
//查找
CNode *Search(CList plist,int key);
//删除
bool DeleteVal(CList plist,int key);
//获取数据节点总数,不包含头
int GetLength(CList plist);
//判空
bool IsEmpty(CList plist);
//清空
void Clear(CList plist);
//摧毁
void Destroy(CList plist);
//输出
void Show(CList plist);
//逆置,******年年考
void Reverse(CList plist);
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "clist.h"
//初始化
void InitList(CList plist)
{
assert(plist!=NULL);
if(plist==NULL)
{
return ;
}
plist->next=plist;
}
//头插
void Insert_head(CList plist,int val)
{
CNode *p=(CNode *)malloc(sizeof(CNode));
p->data=val;
p->next=plist->next;
plist->next=p;
}
//尾插
void Insert_tail(CList plist,int val)
{
CNode *p;
for(p=plist;p->next!=plist;p=p->next);
CNode *q=(CNode *)malloc(sizeof(CNode));
q->data=val;
q->next=p->next;//q->next=plist
p->next=q;
}
//查找
CNode *Search(CList plist,int key)
{
CNode *p;
for(p=plist->next;p!=plist;p=p->next)
{
if(p->data==key)
{
return p;
}
}
return NULL;
}
//删除
bool DeleteVal(CList plist,int key)
{
CNode *p=Search(plist,key);
CNode *q;
if(p==NULL)
{
return false;
}
if(p->next!=plist)
{
q=p->next;
p->data=q->data;
p->next=q->next;
free(q);
}
else
{
for(p=plist;p->next!=plist;p=p->next)
{
if(p->next->data==key)
{
break;
}
}
q=p->next;
p->next=q->next;
free(q);
}
return true;
}
//获取数据节点总数,不包含头
int GetLength(CList plist)
{
int count=0;
CNode *p;
for(p=plist->next;p!=plist;p=p->next)
{
count++;
}
return count;
}
//判空
bool IsEmpty(CList plist)
{
if(plist->next==plist)
{
return true;
}
return false;
//return GetLength(plist)==0;
}
//清空
void Clear(CList plist)
{
Destroy(plist);
}
//摧毁
void Destroy(CList plist)
{
CNode *p;
while(plist->next!=plist)
{
p=plist->next;
plist->next=p->next;
free(p);
}
}
//输出
void Show(CList plist)
{
for(CNode *p=plist->next;p!=plist;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}
#include <stdio.h>
#include "clist.h"
int main()
{
CNode head;
InitList(&head);
for(int i=0;i<20;i++)
{
Insert_head(&head,i);
}
Show(&head);
for(int i=0;i<20;i++)
{
Insert_tail(&head,i);
}
Show(&head);
printf("%d\n",Search(&head,3));
printf("%d\n",Search(&head,0));
printf("%d\n",Search(&head,11));
DeleteVal(&head,3);
Show(&head);
DeleteVal(&head,8);
Show(&head);
DeleteVal(&head,20);
Show(&head);
printf("%d\n",GetLength(&head));
printf("%d\n",IsEmpty(&head));
return 0;
}
静态链表
#pragma once
//静态链表:利用顺序表模拟链表
//有两条链,一条有效数据链,一条空闲链
//有效数据链:带头节点的循环链表,维护有效数据节点,0下标作为链表头
//空链表:带头节点的循环链表,维护空闲节点信息,1下标作为链表头
#define SIZE 10
typedef struct SNode
{
int data;
int next;
}SNode,SLinkList[SIZE],*PList;
//typedef SNode SLinkList[SIZE];
void InitList(PList plist);
//头插
bool Insert_head(PList plist,int val);
//尾插
bool Insert_tail(PList plist,int val);
//删除
bool Delete(PList plist,int key);
void Destroy(PList plist);
void Clear(PList plist);
bool IsEmpty(PList plist);
void Show(PList plist);
#include <stdio.h>
#include <assert.h>
#include "slist.h"
void InitList(PList plist)
{
assert(plist!=NULL);
plist[0].next=0;
for(int i=1;i<SIZE;i++)
{
plist[i].next=i+1;
}
plist[SIZE-1].next=1;
}
//空闲链为空则满
static bool IsFull(PList plist)
{
return plist[1].next==1;
}
//头插
bool Insert_head(PList plist,int val)
{
if(IsFull(plist))
{
return false;
}
int p=plist[1].next;
plist[1].next=plist[p].next;
plist[p].data=val;
plist[p].next=plist[0].next;
plist[0].next=p;
return true;
}
//尾插
bool Insert_tail(PList plist,int val)
{
if(IsFull(plist))
{
return false;
}
int p=plist[1].next;
plist[1].next=plist[p].next;
plist[p].data=val;
int q;
for(q=0;plist[q].next!=0;q=plist[q].next);
plist[p].next=plist[q].next;
plist[q].next=p;
return true;
}
static int SeachPri(PList plist,int key)
{
for(int p=0;plist[p].next!=0;p=plist[p].next)
{
if(plist[plist[p].next].data==key)
{
return p;
}
}
return -1;
}
//删除
bool Delete(PList plist,int key)
{
int p=SeachPri(plist,key);
if(p==-1)
{
return false;
}
int q=plist[p].next;
plist[p].next=plist[q].next;
plist[q].next=plist[1].next;
plist[1].next=q;
return true;
}
void Destroy(PList plist)
{
plist[0].next=0;
}
void Clear(PList plist)
{
Destroy(plist);
}
bool IsEmpty(PList plist)
{
return plist[0].next==0;
}
void Show(PList plist)
{
for(int p=plist[0].next;p!=0;p=plist[p].next)
{
printf("%d ",plist[p].data);
}
printf("\n");
}
#include <stdio.h>
#include "plist.h"
int main()
{
PNode head;
InitPoly(&head);
Insert(&head,2,3);
Insert(&head,2,1);
Insert(&head,5,5);
Insert(&head,4,4);
Insert(&head,5,3);
Show(&head);
PNode head1;
InitPoly(&head1);
Insert(&head1,3,2);
Insert(&head1,1,3);
Insert(&head1,4,1);
Insert(&head1,7,4);
Insert(&head1,5,2);
Show(&head1);
Add(&head,&head1);
Show(&head);
Sub(&head,&head1);
Show(&head);
Destroy(&head);
Show(&head);
return 0;
}
利用带头结点的单链表来描述一元多项式
#pragma once
//利用带头结点的单链表来描述一元多项式
typedef struct PNode
{
double cofe;//系数
int expn;//指数
struct PNode *next;
}PNode,*PList;
void InitPoly(PList pl);
//多项式指数从小到大有序
bool Insert(PList pl,double cofe,int expn);
void Destroy(PList pl);
void Show(PList pl);
//pA+=pB
void Add(PList pA,PList pB);
//pA -= pB
void Sub(PList pA,PList pB);
//pA *= pB
void Multi(PList pA,PList pB);
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "plist.h"
void InitPoly(PList pl)
{
assert(pl!=NULL);
if(pl==NULL)
{
return ;
}
pl->next=NULL;
}
//查找指数expn的前驱
static PNode *SearchPri(PList pl,int expn)
{
PNode *p;
for(p=pl;p->next!=NULL;p=p->next)
{
if(p->next->expn>=expn)
{
break;
}
}
return p;
}
//多项式指数从小到大有序
bool Insert(PList pl,double cofe,int expn)
{
#define EPS 0.0000001
PNode *p=SearchPri(pl,expn);
if(p->next!=NULL&&p->next->expn==expn)
{
PNode *q=p->next;
q->cofe+=cofe;
if(-EPS<=q->cofe&&q->cofe<=EPS)
{
p->next=q->next;
free(q);
}
}
else
{
PNode *q=(PNode *)malloc(sizeof(PNode));
q->cofe=cofe;
q->expn=expn;
q->next=p->next;
p->next=q;
}
return true;
}
void Destroy(PList pl)
{
assert(pl!=NULL);
if(pl==NULL)
{
return;
}
PNode *p;
while(pl->next!=NULL)
{
p=pl->next;
pl->next=p->next;
free(p);
}
}
void Show(PList pl)
{
for(PNode *p=pl->next;p!=NULL;p=p->next)
{
printf("%fx^%d+",p->cofe,p->expn);
}
printf("\n");
}
//pA+=pB
void Add(PList pA,PList pB)
{
PNode *q;
for(q=pB->next;q!=NULL;q=q->next)
{
Insert(pA,q->cofe,q->expn);
}
}
//pA -= pB
void Sub(PList pA,PList pB)
{
PNode *q;
for(q=pB->next;q!=NULL;q=q->next)
{
Insert(pA,-(q->cofe),q->expn);
}
}
//pA *= pB
void Multi(PList pA,PList pB);
#include <stdio.h>
#include "slist.h"
int main()
{
SLinkList s;
InitList(s);
//for(int i=0;i<10;i++)
//{
// Insert_head(s,i);
//}
//Show(s);
for(int i=0;i<10;i++)
{
Insert_tail(s,i);
}
Show(s);
Delete(s,2);
Show(s);
Delete(s,-1);
Show(s);
printf("%d\n",IsEmpty(s));
Destroy(s);
Show(s);
return 0;
}