数据结构
- 线性表
- 顺序表
- 静态分配定义顺序表
- 动态分配定义顺序表
- 顺序表元素插入
- 顺序表元素的删除
- 按位查找元素
- 按值查找元素
- 单链表
- 单链表结构体定义及初始化
- 单链表是否为空
- 单链表_按位插入_不带头结点
- 单链表_按位插入_带头结点
- 单链表_指定节点后插
- 单链表_指定节点前插
- 单链表_按位删除_带头结点
- 单链表_删除指定节点
- 求表长
- 单链表_按位查找
- 单链表_按值查找
- 单链表_建立_尾插法
- 单链表_建立_头插法
- 双链表
- 逻辑结构定义
- 双链表_初始化
- 双链表_判断是否为空
- 双链表_插入_后插
- 双链表_插入_前插
- 双链表_删除
- 双链表_销毁
- 双链表_遍历
- 循环链表
- 循环单链表_逻辑结构定义
- 循环单链表_初始化
- 循环单链表_判断是否为空
- 循环单链表_判断节点p是否为表尾节点
- 循环双链表_逻辑结构定义
- 循环双链表_初始化
- 循环双链表_判断是否为空
- 循环双链表_判断节点p是否为表尾节点
- 静态链表
- 静态链表_逻辑结构定义
线性表
顺序表
静态分配定义顺序表
#include <stdio.h>
#define MaxSize 10
//定义静态结构体
typedef struct{
ElemType data[MaxSize];
int length;
}SqList;
//初始化
void InitList(SqList &L){
for(int i = 0;i < MaxSize;i++){
L.data[i] = 0;
L.length = 0;
}
}
//使用
int main(){
SqList L;
InitList(L);
return 0;
}
动态分配定义顺序表
#include <stdio.h>
//定义动态结构体
#define InitSize 10
typedef struct{
int *data;
int MaxSize;
int length;
}SeqList;
//初始化
void InitList(SeqList &L) {
L.data = (ElemType*)malloc(sizeof(ElemType)*InitSize;
L.length = 0;
L.MaxSize = InitSize;
}
//增加数组长度
void IncreaseSize(SeqList &L, int len){
int *p = L.data;
L.data = (int*)malloc(sizeof(ElemType)*(L.MaxSize+len));
for(int i = 0;i < L.length;i++){
L.data[i] = p[i];
}
L.MaxSize += len;
free(p);
}
//使用
int main(){
SeqList L;
InitList(L);
IncreaseSize(L,5);
return 0;
}
顺序表元素插入
ListInsert(&L,i,e) - 在第i个位置上插入指定元素e
插入的时间复杂度:最好O(1),最坏O(n)
void ListInsert(SqList &L,int i,int e){
for(int j = L.length;j > i;j--){
L.data[j] = L.data[j-1];
}
L.data[i-1] = e;
L.length++;
}
//为了避免插入元素没有反馈,进一步更新
bool ListInsert(SqList &L,int i,int e){
if(i < 1 || i > L.length) //i取值无效,超出范围
return false;
if(L.length >= MaxSize) //满了
return false;
for(int j = L.length;j > i;j--){
L.data[j] = L.data[j-1];
}
L.data[i-1] = e;
L.length++;
return true;
}
顺序表元素的删除
ListDelete(SqList &L,int i,ElemType &e) - 删除第i个元素并返回该元素
删除的时间复杂度:最好O(1),最坏O(n),平均O(n)
bool ListDelete(SqList &L,int i,ElemType &e){
if(i < 1 || i > L.length)
return false;
e = L.data[i-1];
for(int j = i; j < L.length;j++){
L.data[j-1] = L.data[j];
}
L.length--;
return ture;
}
//使用
int main(){
SqList L;
InitList(L);
int e = -1; //注意
if(ListDelete(L,3,e))
printf("删除成功,元素为%d/n",e);
else
printf("删除失败"/n);
return 0;
}
按位查找元素
GetElem(L,i) - 获取表L中的第i个位置的元素的值
按位查找的时间复杂度:O(1)
ElemType GetElem(SqList L,int i){
return L.data[i-1];
}
按值查找元素
LocateElem(SqList L,ElemType e) - 在表中查找给定元素的位置
删除的时间复杂度:最好O(1),最坏O(n),平均O(n)
int LocateElem(SqList L,ElemType e){
for(int i = 0;i < L.length;i++){
if(L.data[i] == e)
return i + 1;
}
return 0;
}
单链表
单链表结构体定义及初始化
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList; //typedef struct LNode;
//typedef struct *LinkList;
bool InitList(LinkList &L){
L = NULL;
return true;
}
//初始化单链表——不带头结点
bool InitList(LinkList &L){
L = NULL; //防止脏数据
return true;
}
//初始化单链表——带头结点
bool InitList(LinkList &L){
L = (LNode*)malloc(sizeof(LNode)); //分配一个头节点
if(L == null) //内存不足,分配失败
return false;
L->next = NULL;
return true;
}
//使用
int main(){
LNode *L; //同样
LinkList L;
InitList(L);
}
单链表是否为空
//带头结点
bool Empty(LinkList L){
if(L->next == NULL)
return true;
else
return false;
}
//不带头结点
bool Empty(LinkList L){
return (L == NULL);
}
单链表_按位插入_不带头结点
时间复杂度为O(n)
bool ListInsert(LinkList &L,int i,ElemType e){
if(i < 1)
return fasle;
if(i == 1){ //第一个节点插入与其他不同
LNode *s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s;
}
LNode *p;
int j = 1;
p = L; //p指针指向L的第一个元素
while(p != NULL && j < i-1){ //使p指向i位置的前一个元素
p = p->next;
j++;
}
if(p == NULL) //i不合法
return false;
//此时p指向要插入元素的前一个元素
LNode *s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
单链表_按位插入_带头结点
时间复杂度为O(n)
bool ListInsert(LinkList &L,int i,ElemType e){
if(i < 1)
return false;
LNode *p;
int j = 0;
p = L;
while(p != NULL && j < i-1){
p = p->next;
j++;
}
if(p == NULL){ //i不合法
return false;
}
//此时p指向要插入元素的前一个元素
LNode*s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
单链表_指定节点后插
InsertNextNode(LinkList &L,int i,ElemType e):在p节点之后插入元素e
主要的时间开销在于查找第i-1个元素,时间复杂度为O(n)
//后插操作
InsertNextNode(LNode *p,ElemType e){
if(p == NULL){ //i不合法
return false;
}
//此时p指向要插入元素的前一个元素
LNode *s = (LNode*)malloc(sizeof(LNode));
if(s == NULL) //内存分配失败
return false;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//使用
bool ListInsert(LinkList &L,int i,ElemType e){
if(i < 1)
return false;
LNode *p;
int j = 0;
p = L;
while(p != NULL && j < i-1){
p = p->next;
j++;
}
return InsertNextNode(p,e);
}
单链表_指定节点前插
InsertPriorNode(LNode *p,ElemType e):在p节点之前插入元素e
正常后插操作,然后交换数据
时间复杂度为O(n)
bool InsertPriorNode(LNode *p,ElemType e){
if(p == NULL)
return false;
//此时p指向要插入元素的前一个元素
LNode *s = (LNode*)malloc(sizeof(LNode));
if(s == NULL) //内存分配失败
return false;
s->next = p->next;
p->next = s;
s->data = p->data;
p->data = e;
return true;
}
单链表_按位删除_带头结点
ListDelete(LinkList &L,int i,ElemType &e):删除第i个位置的元素并带回
算法主要时间开销耗费在查找上,时间复杂度为O(n)
bool ListDelete(LinkList &L,int i,ElemType &e){
if(i < 1)
return false;
LNode *p;
int j = 0;
p = L;
while(p != NULL && j < i-1){
p = p->next;
j++;
}
if(p == NULL)
return false;
if(p->next == NULL)
return false;
LNode *q = p->next;
e = q->data;
p->next = q->next;
free(q);
return true;
}
单链表_删除指定节点
DeleteNode(LNode *p):删除某个给定节点p
p指向要删除的元素
时间复杂度为O(1)
bool DeleteNode(LNode *p){
if(p == NULL)
return false;
LNode *q = p->next;
p->data = q->data; //将p指向元素的下一个元素的数据往前移
p->next = q->next; //将p指向的元素的下下个元素地址给p
free(q); //然后释放q
return true;
}
求表长
Length(LinkList L):求表长
int Length(LinkList L){ //带头结点
if(L->next == NULL){
return 0;
}
LNode *p = L->next;
int len = 1;
while(p != NULL){
p = p->next;
len++;
}
return len;
}
int Length(LinkList L){ //不带头结点
if(L == NULL){
return 0;
}
LNode *p = L;
int len = 1;
while(p != NULL){
p = p->next;
len++;
}
return len;
}
单链表_按位查找
GetElem(LinkList L,int i):按序号查找元素
时间复杂度为O(n)
LNode *GetElem(LinkList L,int i){
if(i == 0){
return L;
}
if(i < 0)
return NULL;
LNode *p = L->next;
int j = 1;
while(p != NULL && j < i){
p = p->next;
j++;
}
return p
}
单链表_按值查找
LocateElem(LinkList L,ElemType e):给定值e,查找元素
时间复杂度为O(n)
LNode *LocateElem(LinkList L,ElemType e){
LNode *p = L->next; //默认带头结点
while(p != NULL && p->data != e)
p = p->next;
return p;
}
单链表_建立_尾插法
List_TailInsert(LinkList &L):初始化一个单链表,并依次读取值添加至表尾
设单链表的长度为n,则时间复杂度为O(n)
LinkList List_TailInsert(LinkList &L){
ElemType e;
L = (LinkList)malloc(sizeof(LNode)); //建立头节点
LNode *s,*r = L; //r表尾指针,s新结点指针
scanf("%d",&e);
while(e != 9999){ //9999代表结束
s = (LNode*)malloc(sizeof(LNode));
s->data = e;
r->next = s;
r = s; //使r指向表尾
scanf("%d",&e);
}
r->next = NULL;
return L;
}
单链表_建立_头插法
List_TailInsert(LinkList &L):初始化一个单链表,并依次读取值添加至表头
时间复杂度为O(n)
LinkList List_TailInsert(LinkList &L){
ElemType e;
LNode *s;
L = (LinkList)malloc(sizeof(LNode)); //建立头节点
L->next = NULL;
scanf("%d",&e);
while(e != 9999){ //9999代表结束
s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = L->next;
L->next = s;
scanf("%d",&e);
}
return L;
}
双链表
逻辑结构定义
typedef struct DNode{
ElemType data;
struct DNode *prior,*next;
}DNode,*DLinkList;
双链表_初始化
InitDLinkList(DLinkList &L):初始化
bool InitDLinkList(DLinkList &L){
L = (DNode*)malloc(sizeof(DNode));
if(L == NULL)
return false;
L->prior = NULL;
L->next = NULL;
return true;
}
双链表_判断是否为空
Empty(DLinkList L):判断是否为空
bool Empty(DLinkList L){
return (L->next == NULL);
}
双链表_插入_后插
InsertNextDNode(DNode p,DNode s):在双链表p所指节点后面插入结点s
bool InsertNextDNode(DNode *p,DNode *s){
s->next = p->next;
p->next->prior = s;
p->next = s;
s->prior = p;
return true;
}
双链表_插入_前插
InsertNextDNode(DNode *p,DNode s):在双链表p所指节点前插入节点s
bool InsertNextDNode(DNode *p,DNode *s){
s->prior = p->prior;
p->prior->next = s;
s->next = p;
p->prior = s
return true;
}
双链表_删除
bool DeleteDNode(DNode *p):删除p节点的后继节点q
bool DeleteDNode(DNode *p){
if(p == NULL)
return false;
DNode *q = p->next; //找到p的下一个节点
if(q == NULL)
return false;
q->next->prior = p;
p->next = q->next;
free(q);
return true;
}
双链表_销毁
void DestoryList(DLinkList &L):销毁链表
void DestoryList(DLinkList &L){
while(L->next == NULL)
DeleteDNode(DNode *p); //从头开始删除
free(L); //剩下头节点--释放
L = NULL; !!!?
}
双链表_遍历
while(p != NULL) //向后遍历
p = p->next;
while(p != NULL) //向前遍历
p = p->prior;
//while(p->prior != NULL) //向前遍历(跳过头结点)
// p = p->prior; !!!?
循环链表
循环单链表_逻辑结构定义
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
循环单链表_初始化
bool InitList(LinkList &L){
L = (LNode*)malloc(sizeof(LNode));
if(L == NULL) //内存不足
return false;
L->next = L;
return true;
}
循环单链表_判断是否为空
bool Empty(LinkList L){
return L->next == L;
}
循环单链表_判断节点p是否为表尾节点
bool Empty(LinkList L,LNode *p){
return p->next == L;
}
循环双链表_逻辑结构定义
typedef struct DNode{
ElemType data;
struct DNode *prior,*next;
}DNode,*DLinkList;
循环双链表_初始化
bool InitDLinkList(DLinkList &L){
L = (DNode*)malloc(sizeof(DNode));
if(L == NULL) //内存不足
return false;
L->next = L;
L->prior = L;
return true;
}
循环双链表_判断是否为空
bool Empty(DLinkList L){
return L->next == L;
}
循环双链表_判断节点p是否为表尾节点
bool Empty(DLinkList L,DNode *p){
return p->next == L;
}
静态链表
静态链表_逻辑结构定义
define MaxSize 10
typedef struct{
ElemType data;
int next;
}SLinkList[MaxSize]
int main(){
SLinkList s;
}