准备24考研、复习数据结构中,闲来无事,就将自己整理的数据结构重点代码的实现发布出来。大家捧捧场,有错误就找个错误,发表在在评论区里,大家一起进步。没错误的话,大家也可以参考参考它实现。持续更新中…
参考:数据结构(严蔚敏版)、王道考研数据结构课程,力扣
文章目录
第一章 线性表
顺序表
/* 顺序表: sequence list
* 动态分配
*/
#define InitSize 100
typedef struct {
int *data;
int length;
int MaxSize;
}SqList;
/*初始化*/
bool InitList(SqList &L) {
L.data = (int *)malloc(InitSize * sizeof(int));
if (L.data == nullptr)
return false;
L.length = 0;
L.MaxSize = InitSize;
return true;
}
/*扩容*/
bool IncreaseSize(SqList &L, int len) {
int *p = L.data;
L.data = (int *) malloc((L.length + len) * sizeof(int));
if (L.data == nullptr)
return false;
for (int i = 0; i < L.length; ++i) {
L.data[i] = p[i];
}
L.MaxSize = L.MaxSize + len;
free(p);
return true;
}
/*将elem元素插入位序为order的地方*/
bool ListInsert(SqList &L, int order, int elem) {
if (order < 1 || order > L.length + 1) //判断order的取值范围是否有效
return false;
if (L.length >= L.MaxSize) //当前存储空间已满,不能插入
return false;
for (int i = L.length; i >= order; --i) { //将将第order个元素及之后元素后移
L.data[i] = L.data[i-1];
}
L.data[order-1] = elem;
L.length++;
return true;
}
/*将位序order的元素删除,并将值传给elem*/
bool ListDelete(SqList &L, int order, int &elem) {
if (order < 1 || order > L.length) //判断order的取值是否有效
return false;
elem = L.data[order-1]; //将第order个元素赋值给elem
for (int i = order; i < L.length; ++i) { //将第order个后面的元素前移
L.data[i-1] = L.data[i];
}
L.length--;
return true;
}
/*根据元素elem,查找位序*/
int LocateElem(SqList &L, int elem) {
for (int i = 0; i < L.length; ++i) {
if (L.data[i] == elem)
return i + 1; //下标为i,位序为i+1
}
return -1; //查找失败,返回-1
}
/*根据位序,查找元素*/
int GetElem(SqList L, int order) {
return L.data[order-1];
}
/*打印顺序表*/
void ListPrint(SqList &L) {
for (int i=0; i<L.length; ++i) {
printf("下标%3d 位序%3d : %d\n", i, i+1, L.data[i]);
}
}
单链表(带头节点)
/* 单链表:
* 带头节点
*/
typedef struct LNode {
int data;
struct LNode *next;
}LNode, *LinkList; //LNode强调这是节点、LinkList强调这是单链表
/*初始化*/
bool InitList(LinkList &L) {
L = (LNode*) malloc(sizeof(LNode));
if (L == nullptr)
return false;
L->next = nullptr;
return true;
}
/*链表判空*/
bool Empty(LinkList L) {
return L->next == nullptr;
}
/*将元素elem插入位序为order的位置*/
bool ListInsert(LinkList &L, int order, int elem) {
if (order < 1)
return false;
LNode *p = L;
int i = 0;
while (p != nullptr && i < order - 1) {
p = p->next;
i++;
}
if (p == nullptr)
return false;
LNode *s = (LNode*) malloc(sizeof(LNode));
s->data = elem;
s->next = p->next;
p->next = s;
return true;
}
/*指定节点的后插操作*/
bool InsertNextNode(LNode *p, int elem) {
if (p == nullptr)
return false;
LNode *s = (LNode*) malloc(sizeof(LNode));
if (s == nullptr) //节点分配失败
return false;
s->data = elem;
s->next = p->next;
p->next = s;
return true;
}
/*指定节点的前插操作*/
bool InsertPriorNode(LNode *p, int elem) {
if (p == nullptr)
return false;
LNode *s = (LNode*) malloc(sizeof(LNode));
if (s == nullptr) //节点分配失败
return false;
//核心:将s和p节点的data内容调换
s->next = p->next;
p->next = s;
s->data = p->data;
p->data = elem;
return true;
}
/*按位序删除*/
bool ListDelete(LinkList &L, int order, int &elem) {
if (order < 1)
return false;
LNode *p = L;
int i = 0;
while (p != nullptr && i < order - 1) {
p = p->next;
i++;
}
if (p == nullptr) //节点不合法
return false;
if (p->next == nullptr) //节点不合法,第order-1个节点为最后一个节点,无后继节点
return false;
LNode *q = p->next;
elem = q->data;
p->next = q->next;
free(q);
return true;
}
/*删除指定节点*/
bool DeleteNode(LNode *p) {
if (p == nullptr)
return false;
//偷天换日核心:将p的后继节点q的内容复制到p节点,并删除p的后继节点
//注意:若p的后继节点q为NULL,则失败。
if (p->next == nullptr)
return false;
LNode *q = p->next;
p->data = p->data;
p->next = q->next;
free(q);
return true;
}
/*根据位序,查找元素节点*/
LNode* GetElem(LinkList L, int order) {
if (order < 0)
return nullptr;
LNode *p = L;
int i = 0;
while (p != nullptr && i < order) {
p = p->next;
++i;
}
return p;
}
/*根据元素,查找位序节点*/
LNode* LocateElem(LinkList L, int elem) {
LNode *p = L->next;
while (p != nullptr && p->data != elem) {
p = p->next;
}
return p;
}
/*求单链表长度*/
int Length(LinkList L) {
int len = 0;
LNode *p = L;
while (p->next != nullptr) {
p = p->next;
len++;
}
return len;
}
单链表(不带头节点)
/* 单链表:
* 不带头节点
*/
typedef struct LNode {
int data;
struct LNode *next;
}LNode, *LinkList; //LNode强调这是节点、LinkList强调这是单链表
/*初始化*/
bool InitList(LinkList &L) {
L = nullptr;
return true;
}
/*链表判空*/
bool Empty(LinkList L) {
return L->next == nullptr;
}
/*将元素elem插入位序为order的位置*/
bool ListInsert(LinkList &L, int order, int elem) {
if (order < 1)
return false;
if (order == 1) {
LNode *s = (LNode*) malloc(sizeof(LNode));
s->data = elem;
s->next = L;
L = s;
return true;
}
LNode *p = L;
int i = 1;
while (p != nullptr && i < order - 1) {
p = p->next;
i++;
}
if (p == nullptr)
return false;
LNode *s = (LNode*) malloc(sizeof(LNode));
s->data = elem;
s->next = p->next;
p->next = s;
return true;
}
/*指定节点的后插操作*/
bool InsertNextNode(LNode *p, int elem) {
if (p == nullptr)
return false;
LNode *s = (LNode*) malloc(sizeof(LNode));
if (s == nullptr) //节点分配失败
return false;
s->data = elem;
s->next = p->next;
p->next = s;
return true;
}
/*指定节点的前插操作*/
bool InsertPriorNode(LNode *p, int elem) {
if (p == nullptr)
return false;
LNode *s = (LNode*) malloc(sizeof(LNode));
if (s == nullptr) //节点分配失败
return false;
//核心:将s和p节点的data内容调换
s->next = p->next;
p->next = s;
s->data = p->data;
p->data = elem;
return true;
}
/*按位序删除*/
bool ListDelete(LinkList &L, int order, int &elem) {
if (order < 1)
return false;
if (order == 1 && L != nullptr) {
LNode *p = L;
L = L->next;
free(p);
return true;
}
LNode *p = L;
int i = 1;
while (p != nullptr && i < order - 1) {
p = p->next;
i++;
}
if (p == nullptr) //节点不合法
return false;
if (p->next == nullptr) //节点不合法,第order-1个节点为最后一个节点,无后继节点
return false;
LNode *q = p->next;
elem = q->data;
p->next = q->next;
free(q);
return true;
}
/*删除指定节点*/
bool DeleteNode(LNode *p) {
if (p == nullptr)
return false;
//偷天换日核心:将p的后继节点q的内容复制到p节点,并删除p的后继节点
//注意:若p的后继节点q为NULL,则失败。
if (p->next == nullptr)
return false;
LNode *q = p->next;
p->data = p->data;
p->next = q->next;
free(q);
return true;
}
/*根据位序,查找元素节点*/
LNode* GetElem(LinkList L, int order) {
if (order < 0)
return nullptr;
LNode *p = L;
int i = 1;
while (p != nullptr && i < order) {
p = p->next;
++i;
}
return p;
}
/*根据元素,查找位序节点*/
LNode* LocateElem(LinkList L, int elem) {
LNode *p = L;
while (p != nullptr && p->data != elem) {
p = p->next;
}
return p;
}
/*求单链表长度*/
int Length(LinkList L) {
if (L == nullptr)
return 0;
int len = 1;
LNode *p = L;
while (p->next != nullptr) {
p = p->next;
len++;
}
return len;
}
双链表(带头节点)
/* 双链表:
* 带头节点
*/
typedef struct LNode {
int data;
struct LNode *prior, *next;
}DNode, *DLinkList;
/*初始化*/
bool InitList(DLinkList &L) {
L = (DNode*) malloc(sizeof(DNode));
if (L == nullptr)
return false;
L->prior = nullptr; //头节点的prior永远指向nullptr
L->next = nullptr;
return true;
}
/*链表判空*/
bool Empty(DLinkList L) {
return L->next == nullptr;
}
/*在p节点之后插入s节点*/
bool InsertNextDNode(DNode *p, DNode *s) {
if (p == nullptr || s == nullptr)
return false;
s->next = p->next;
if (p->next != nullptr)
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
/*删除p节点的后继节点*/
bool DeleteNextDNode(DNode *p) {
if (p == nullptr)
return false;
DNode *q = p->next;
if (q == nullptr)
return false;
p->next = q->next;
if (q->next != nullptr)
q->next->prior = p;
free(q);
return true;
}
循环单链表(带头节点)
/* 循环单链表:
* 带头节点
*/
typedef struct LNode {
int data;
struct LNode *next;
}LNode, *LinkList;
/*初始化*/
bool InitList(LinkList &L) {
L = (LNode*) malloc(sizeof(LNode));
if (L == nullptr)
return false;
L->next = L; //头节点的next指向头节点
return true;
}
/*判空*/
bool Empty(LinkList L) {
return L->next == L;
}
/*判断节点p是否为循环单链表的尾节点*/
bool isTail(LinkList L, LNode *p) {
return p->next == L;
}
循环双链表(带头节点)
/* 循环双链表:
* 带头节点
*/
typedef struct LNode {
int data;
struct LNode *prior, *next;
}DNode, *DLinkList;
/*初始化*/
bool InitList(DLinkList &L) {
L = (DNode*) malloc(sizeof(DNode));
if (L == nullptr)
return false;
L->prior =L; //头节点的prior指向头节点
L->next = L; //头节点的next指向头节点
return true;
}
/*链表判空*/
bool Empty(DLinkList L) {
return L->next == L;
}
/*判断节点p是否为循环双链表的尾节点*/
bool isTail(DLinkList L, DNode *p) {
return p->next == L;
}
/*p节点之后插入s节点*/
bool InsertNextDNode(DNode *p, DNode *s) {
s->next = p->next;
p->next->prior = s;
s->prior = p;
p->next = s;
}
/*删除p节点的后继节点*/
bool DeleteNextDNode(DNode *p) {
if (p == nullptr) //漏洞:当删除的节点为最后一个节点时,任有错误,不能删除头节点
return false;
DNode *q = p->next;
p->next = q->next;
q->next->prior = p;
free(q);
return true;
}
静态链表
/* 静态链表:
*/
#define MaxSize 100
typedef struct {
int data;
int next;
}SLinkList[MaxSize]; //强调为静态链表,等价于Node node = Node[MaxSize];强调为Node型数组
第二章 栈和队列
顺序栈
/* 顺序栈:
* 本版本初始时:栈顶栈顶指针指向-1,即栈顶指针指向栈顶元素
* 其他版本:栈顶栈顶指针指向0,即栈顶指针指向栈顶元素的上位、各操作需修改
*/
#define MaxSize 100
typedef struct {
int data[MaxSize]; //存放栈中元素
int top; //栈顶指针
}SqStack;
/*栈的初始化*/
void InitStack(SqStack &S) {
S.top = -1; //初始为-1,不指向任何元素
}
/*栈判空*/
bool StackEmpty(SqStack S) {
return S.top == -1;
}
/*入栈*/
bool Push(SqStack &S, int elem) {
if (S.top == MaxSize - 1)
return false;
S.data[++S.top] = elem;
return true;
}
/*出栈,将出栈元素的结果保存在elem中*/
bool Pop(SqStack &S, int &elem) {
if (S.top == -1)
return false;
elem = S.data[S.top--];
return true;
}
/*取栈顶元素,并将栈顶元素的结果保存在elem中*/
bool GetTop(SqStack &S, int &elem) {
if (S.top == -1)
return false;
elem = S.data[S.top];
return true;
}
链栈(带头节点)
/* 链栈:
* 带头节点
*/
typedef struct LNode{
int data;
struct LNode *next;
}LNode,LinkStack;
/*栈的初始化*/
void InitStack(LinkStack &S) {
S.next = nullptr;
}
/*栈判空*/
bool StackEmpty(LinkStack S) {
return S.next == nullptr;
}
/*入栈*/
bool Push(LinkStack &S, int elem) {
LNode *s = (LNode*) malloc(sizeof(LNode));
s->data = elem;
s->next = S.next;
S.next = s;
return true;
}
/*出栈,将出栈元素的结果保存在elem中*/
bool Pop(LinkStack &S, int &elem) {
if (S.next == nullptr)
return false;
LNode *p = S.next;
S.next = p->next;
elem = p->data;
free(p);
return true;
}
/*取栈顶元素,并将栈顶元素的结果保存在elem中*/
bool GetTop(LinkStack &S, int &elem) {
if (S.next == nullptr)
return false;
elem = S.next->data;
return true;
}
循环队列
/* 循环队列:
* 初始时,队头front、队尾rear指针都指向0,最终有一个元素被浪费,用于判满 (rear + 1) % MaxSize == front
* 不允许元素被浪费:设置size(记录长度)、设置tag(记录最后一次操作是插入还是删除)
*/
#define MaxSize 100
typedef struct {
int data[MaxSize];
int front, rear;
}SqQueue;
/*初始化*/
void InitQueue(SqQueue &Q) {
Q.rear = 0; //初始时,队尾,队头指针都指向0
Q.front = 0;
}
/*判空*/
bool QueueEmpty(SqQueue Q) {
return Q.front == Q.rear;
}
/*入队*/
bool EnQueue(SqQueue &Q, int elem) {
if ((Q.rear + 1) % MaxSize == Q.front) //队列判满,有一个元素位置被浪费,用于判满
return false;
Q.data[Q.rear] = elem;
Q.rear = (Q.rear + 1) % MaxSize;
return true;
}
/*出队*/
bool DeQueue(SqQueue &Q, int &elem) {
if (Q.rear == Q.front)
return false;
elem = Q.data[Q.front];
Q.front = (Q.front + 1) % MaxSize;
return true;
}
/*获取队头元素*/
bool GetHead(SqQueue Q, int &elem) {
if (Q.rear == Q.front)
return false;
elem = Q.data[Q.front];
return true;
}
链队
/* 链式队列:
* 带头节点
*/
typedef struct LinkNode {
int data;
struct LinkNode *next;
};
typedef struct {
LinkNode *front, *rear;
}LinkQueue;
/*初始化*/
void InitQueue(LinkQueue &Q) {
Q.front = Q.rear = (LinkNode*) malloc(sizeof(LinkNode));
Q.front->next = nullptr;
}
/*判空*/
bool IsEmpty(LinkQueue Q) {
return Q.rear == Q.front;
}
/*入队*/
void EnQueue(LinkQueue &Q, int elem) {
LinkNode *s = (LinkNode*) malloc(sizeof(LinkNode));
s->data = elem;
s->next = nullptr;
Q.rear->next = s; //新结点插入到rear之后
Q.rear = s; //修改尾指针
}
/*出队*/
bool DeQueue(LinkQueue &Q, int &elem) {
if (Q.front == Q.rear)
return false;
LinkNode *p = Q.front->next;
elem = p->data;
Q.front->next = p->next;
if (Q.rear == p) //如果是最后一个元素,则修改队尾指针
Q.rear = Q.front;
free(p);
return true;
}
/*获取队头元素*/
bool GetHead(LinkQueue Q, int &elem) {
if (Q.rear == Q.front)
return false;
elem = Q.front->next->data;
return true;
}
后缀表达式-逆波兰表达式(Java实现)
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
int n = tokens.length;
for (int i = 0; i < n; i++) {
String token = tokens[i];
if (isNumber(token)) {
stack.push(Integer.parseInt(token));
} else {
int num2 = stack.pop();
int num1 = stack.pop();
switch (token) {
case "+":
stack.push(num1 + num2);
break;
case "-":
stack.push(num1 - num2);
break;
case "*":
stack.push(num1 * num2);
break;
case "/":
stack.push(num1 / num2);
}
}
}
return stack.pop();
}
public boolean isNumber(String token) {
return !("+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token));
}
}
链接:https://leetcode.cn/problems/8Zf90G/
来源:力扣(LeetCode)
第三章 字符串
KMP(Java实现)
class Solution {
public static int[] getNext(String t) {
int n = t.length(), i = 0, j = -1;
int[] next = new int[n];
next[0] = -1;
while (i < n - 1) {
if (j == -1 || t.charAt(i) == t.charAt(j)) {
next[++i] = ++j;
} else {
j = next[j];
}
}
return next;
}
public static int strStr(String haystack, String needle) {
if (needle.length() == 0) {
return 0;
}
int[] next = getNext(needle);
int n = haystack.length(), m = needle.length(), i = 0, j = 0;
while (i < n && j < m) {
if (j == -1 || haystack.charAt(i) == needle.charAt(j)) {
i++;
j++;
} else {
j = next[j];
}
}
return (j == m) ? i - j : -1;
}
}
链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/
来源:力扣(LeetCode)