顺序表若时间复杂度有限制,则考虑再创一个数组并把要求的写入新数组,最后返回去,若为void函数则考虑赋值过去并更新len
顺序表若空间复杂度有限制,则考虑多几次循环处理
线性表插入
从后往前依次后推一个
bool InsList(LListPtr L, int i, ElemType e) {
//当插入位置不合理时
if (i < 1 || i > L->last + 2)
return false;
for (int j = L->last; j >= i - 1; --j)
L->elem[j + 1] = L->elem[j];
L->elem[i - 1] = e;
++L->last;
return true;
}
线性表删除
bool DelList(LListPtr L, int i, ElemType *e) {
if (i < 1 || i > L->last + 1)
return false;
*e = L->elem[i - 1];//删除i位置,因为开头是0所以i-1
for (int j = i - 1; j < L->last; ++j)
L->elem[j] = L->elem[j + 1];
--L->last;
return true;
}
链表
链表插入删除定位
for (; p != NULL && k < i; ++k) p = p->next;//找到位置
//如果遍历完了链表,还没有数到i-1,则说明插入位置不合理
if (p->next == NULL)
return false;
栈
- 注意箭头指示结构体元素
- 注意压栈弹栈前判满判空
- 消除递归思路
//定义
typedef int elemtype;
struct Stack {
int top;
int capacity;
elemtype* elem;
};
判满判空
bool is_empty(stackptr s)
{
if s->top == -1
return true;
}
bool is_full (stackptr s)
{
if s->top == capacity-1;
return true;
}
压栈弹栈
bool push(stackptr s;elemtype x)
{
if(is_full(s))return false;
++s->top;
s->elem[s->top]==x;//注意用箭头指示结构体对应元素
}
bool pop(stackptr s;elemtype x)
{
if (is_empty(s)) return false;
*x = s->elem[s->top];//解引用指针操作
--s->top;
}
深度优先搜索消除递归
//树的先序遍历
void pre(tree root)
stack s;
init_stack(s);
push(&s,root);
while(!is_empty(s))
{
pop(&s;&new);
if(new!=NULL)
visit_node(new);
else continue;
if(new->right!=NULL)
push(&s,new->right);
if(new->left!=NULL)
push(&s,new->left);
}
先序口诀:建栈初始化,压入根节点,循环非空栈,弹出栈顶点,访问当前点,压入后续点
后序:因为要先找到左子树,所以要用栈记录左走路径
//后序
void PostOrder(BiTree root, CALLBACK Visit) {
BiTNode *p, *q;
Stack s, *S = &s;
q = NULL;
p = root;
InitStack(&S);
while (p != NULL || !IsEmpty(S)) {
if (p != NULL) {
Push(S, p);
p = p->LChild;//走左子树
} else {
//左边走到头
GetTop(S, &p);
if (p->RChild == NULL || p->RChild == q) {
Pop(S, &p);//弹出当前源结点,没有右子树或者访问过就回溯
Visit(p->data);
q = p;//记为已读
p = NULL;
} else {
p = p->RChild;
}
}
}
ClearStack(S);
}
//中序
void InOrder(BiTree root, CALLBACK Visit) {
/* 中序遍历二叉树的非递归算法 */
Stack s, *S = &s;
BiTree p;
InitStack(&S);
p = root;
while (p != NULL || !IsEmpty(S)) {
if (p != NULL) {
Push(S, p);
p = p->LChild;//记录左走路径
} else {
Pop(S, &p);//弹出当前源节点
Visit(p->data);