数据结构及其面试题

162 阅读5分钟

面试题及其答案

面试题及其答案

堆栈

顺序栈

定义

typedef int ElementType;
typedef int Position;
// 顺序栈
typedef struct SNode *Stack;
struct SNode {
    ElementType *Data;
    Position Top;
    int MaxSize;
};

创建栈

Stack CreateStack( int MaxSize )
{
    if (MaxSize <= 0) {
        
    }
    Stack S = (Stack)malloc(sizeof(struct SNode));
    S->Data = (ElementType *)malloc(sizeof(ElementType) * MaxSize);
    S->Top = -1;
    S->MaxSize = MaxSize;
    return S;
}

栈满

bool IsFull( Stack S )
{
    return (S->Top == S->MaxSize - 1);
}

栈空

bool IsEmpty( Stack S )
{
    return (S->Top == -1);
}

压栈

bool Push( Stack S, ElementType X )
{
    if (IsFull(S)) {
        printf("堆栈已满无法压入");
        return false;
    }
    S->Data[++(S->Top)] = X;
    return true;
}

弹栈

ElementType Pop( Stack S )
{
    if (IsEmpty(S)) {
        printf("堆栈已空无法弹出");
        return false;
    }
    return S->Data[(S->Top)--];
}

链表栈

定义

typedef int ElementType;
typedef int Position;
typedef struct SLinkNode *LinkStack;
struct SLinkNode {
    ElementType Data;
    LinkStack Next;
};

创建栈

LinkStack CreateLinkStack( )
{
    LinkStack Stack = (LinkStack)malloc(sizeof(struct SLinkNode));
    Stack->Next = NULL;
    return Stack;
}

栈空

bool LinkStackIsEmpty( LinkStack S )
{
    return (S->Next == NULL);
}

压栈

bool LinkStackPush( LinkStack S, ElementType X )
{
    LinkStack N = (LinkStack)malloc(sizeof(struct SLinkNode));
    N->Data = X;
    N->Next = S->Next;
    S->Next = N;
    return true;
}

弹栈

ElementType LinkStackPop( LinkStack S )
{
    if (LinkStackIsEmpty(S)) {
        printf("堆栈已空无法弹出");
        return -1;
    }
    LinkStack N = S->Next;
    ElementType Data = N->Data;
    S->Next = N->Next;
    free(N);
    return Data;
}

队列

顺序队列

定义

typedef int Position;
typedef int ElementType;
struct QNode {
    ElementType *Data;     /* 存储元素的数组 */
    Position Front, Rear;  /* 队列的头、尾指针 */
    int MaxSize;           /* 队列最大容量 */
};
typedef struct QNode *Queue;

创建

Queue CreateQueue( int MaxSize )
{
    Queue Q = (Queue)malloc(sizeof(struct QNode));
    Q->Rear = 0;
    Q->Front = 0;
    Q->Data = (ElementType *)malloc(sizeof(ElementType) * MaxSize);
    Q->MaxSize = MaxSize;
    return Q;
}

队列空

bool QueueIsEmpty( Queue Q )
{
   return (Q->Rear == Q->Front);
}

队列满

bool QueueIsFull( Queue Q )
{
    return ((Q->Rear + 1) % Q->MaxSize == Q->Front);
}

入队

bool AddQ( Queue Q, ElementType X )
{
    if(QueueIsFull(Q)) {
        printf("队列已满");
        return false;
    }
    Q->Data[Q->Rear] = X;
    Q->Rear = (++Q->Rear) % Q->MaxSize;
    return true;
}

出队

ElementType DeleteQ( Queue Q )
{
    if (QueueIsEmpty(Q)) {
        printf("队列已空");
        return false;
    }
    ElementType Data = Q->Data[Q->Front];
    Q->Front = (++Q->Front) % Q->MaxSize;
    return Data;
}

链式队列

定义

typedef struct Node *PtrNode;
struct Node {
    ElementType Data;
    PtrNode Next;
};

typedef struct QLinkNode {
    PtrNode Front;
    PtrNode Rear;
    int MaxSize;
}* LinkQueue;

创建

LinkQueue CreateLinkQueue( int MaxSize ) {
    LinkQueue Q = (LinkQueue)malloc(sizeof(struct QLinkNode));
    Q->MaxSize = MaxSize;
    PtrNode H = (PtrNode)malloc(sizeof(struct Node));
    H->Next = NULL;
    Q->Front = H;
    Q->Rear = H;
    return Q;
}

队列空

bool LinkQueueIsEmpty( LinkQueue Q ) {
    return Q->Front == Q->Rear;
}

队列长

int LinkQueueLength( LinkQueue Q ) {
    int MaxSize = 0;
    PtrNode front = Q->Front->Next;
    while (front && MaxSize != Q->MaxSize) {
        MaxSize++;
        front = front->Next;
    }
    return MaxSize;
}

队列满

bool LinkQueueIsFull( LinkQueue Q ) {
    return (LinkQueueLength(Q) == Q->MaxSize);
}

入队

bool AddLinkQ( LinkQueue Q, ElementType X ) {
    if (LinkQueueIsFull(Q)) {
        printf("链表队列已满\n");
        return false;
    }
    PtrNode N = (PtrNode)malloc(sizeof(struct Node));
    N->Data = X;
    N->Next = NULL;
    Q->Rear->Next = N;
    Q->Rear = N;
    return true;
}

出队

ElementType DeleteLinkQ( LinkQueue Q ) {
    if (LinkQueueIsEmpty(Q)) {
        printf("链表队列已空\n");
    }
    PtrNode N = Q->Front->Next;
    Q->Front->Next = N->Next;
    ElementType Data = N->Data;
    free(N);
    return Data;
}

二叉树

定义

typedef struct TreeNode *Tree;
struct TreeNode {
    char Data;
    Tree Left, Right;
    bool flag; // 是否访问过
};

typedef Tree ElementType;

先序遍历

递归

void preorderTraversal(Tree Root) {
    if (!Root) {
        return;
    }
    printf("%c ", Root->Data);
    preorderTraversal(Root->Left);
    preorderTraversal(Root->Right);
}

非递归

void preorderNotRecursionTraversal(Tree Root) {
    Stack S = CreateStack(20);
    while (Root || !IsEmpty(S)) {
        if (Root) {
            Push(S, Root);
            printf("%c ", Root->Data);
            Root = Root->Left;
        }

        if (!Root) {
            Root = Pop(S);
            Root = Root->Right;
        }
    }
}

中序遍历

递归

void inorderTraversal(Tree Root) {
    if (!Root) {
        return;
    }
    inorderTraversal(Root->Left);
    printf("%c ", Root->Data);
    inorderTraversal(Root->Right);
}

非递归

void inorderNotRecursionTraversal(Tree Root) {
    Stack S = CreateStack(20);
    while (Root || !IsEmpty(S)) {
        if (Root) {
            Push(S, Root);
            Root = Root->Left;
        }

        if (!Root) {
            Root = Pop(S);
            printf("%c ", Root->Data);
            Root = Root->Right;
        }
    }
}

后序遍历

递归

void postorderTraversal(Tree Root) {
    if (!Root) {
        return;
    }
    postorderTraversal(Root->Left);
    postorderTraversal(Root->Right);
    printf("%c ", Root->Data);
}

非递归

void postorderNotRecursionTraversal(Tree Root) {
    Stack S = CreateStack(20);
    while (Root || !IsEmpty(S)) {
        if (Root) {
            Push(S, Root);
            Root = Root->Left;
        }

        if (!Root) {
            Tree Top = TopElement(S);
            if (Top->flag) { // 已经访问过弹出
                Top = Pop(S);
                printf("%c ", Top->Data);
                Root = NULL; // MARK
            } else { // 先不弹出 设置标志位
                Root = Top;
                Root->flag = true;
                Root = Root->Right;
            }
        }
    }
}

层序遍历

void levelTraversal(Tree Root) {
    Queue Q = CreateQueue(100);
    if (Root) {
        AddQ(Q, Root);
    }
    while (!QueueIsEmpty(Q)) {
        Tree T = DeleteQ(Q);
        printf("%c ", T->Data);
        if (T->Left) {
            AddQ(Q, T->Left);
        }
        if (T->Right) {
            AddQ(Q, T->Right);
        }
    }
}

树的高度

#define CMAX(a,b) ((a) > (b) ? (a) : (b))
int lengthOfTree(Tree Root) {
    if (!Root) {
        return 0;
    }
    return CMAX(lengthOfTree(Root->Left), lengthOfTree(Root->Right)) + 1;
}

二叉搜索树

  • 根节点大于左子树根节点
  • 根节点小于右子树根节点
  • 左右子树也符合以上条件

定义

typedef int ElementType;

typedef struct BinTreeNode *BinTree;

struct BinTreeNode {
    BinTree Left, Right;
    ElementType Data;
};

创建二叉搜索树

BinTree CreateBinTree(ElementType X)
{
    BinTree BT = (BinTree)malloc(sizeof(struct BinTreeNode));
    BT->Data = X;
    BT->Left = BT->Right = NULL;
    return BT;
}

查找

BinTree FindX(BinTree BT, ElementType X)
{
    while (BT && BT->Data != X) {
        if (BT->Data > X) {
            BT = BT->Left;
        } else {
            BT = BT->Right;
        }
    }
    return BT;
}

查找最大

BinTree FindMax(BinTree BT)
{
    if (!BT) {
        return BT;
    }
    while (BT->Right) {
        BT = BT->Right;
    }
    return BT;
}

查找最小

BinTree FindMin(BinTree BT)
{
    if (!BT) {
        return BT;
    }
    while (BT->Left) {
        BT = BT->Left;
    }
    return BT;
}

插入

BinTree InsertX(BinTree BT, ElementType X)
{
    if (!BT) { // 找到插入位置
        BinTree N = CreateBinTree(X);
        return N;
    }
    if (BT->Data > X) {
        BT->Left = InsertX(BT->Left, X);
    } else if (BT->Data < X){
        BT->Right = InsertX(BT->Right, X);
    }
    return BT;
}

删除

BinTree DeleteX(BinTree BT, ElementType X)
{
    if (BT->Data == X) {
        // 找到待删除节点
        BinTree Temp = NULL;
        if (!BT->Left && !BT->Right) {
            // 删除叶子节点
            free(BT);
            return NULL;
        } else if (BT->Left && BT->Right) {
            // 删除度二节点
            // BT左子树最小节点 BT右子树最大节点度肯定小于1
            Temp = FindMax(BT->Right);
            BT->Data = Temp->Data;
            BT->Right = DeleteX(BT->Right, Temp->Data);
        } else {
            // 删除度一节点
            if (BT->Left) {
                Temp = BT->Left;
            }
            if (BT->Right) {
                Temp = BT->Right;
            }
            free(BT);
            return Temp;
        }
    } else if (BT->Data > X) { // 左子树
        BT->Left = DeleteX(BT->Left, X);
    } else { // 右子树
        BT->Right = DeleteX(BT->Right, X);
    }
    return BT;
}