c数据结构算法面试笔试题_笔试题目

标题:C 数据结构算法面试笔试题:全面解析笔试题目,助你应试无忧

c数据结构算法面试笔试题_笔试题目

摘要:本文将详细介绍C语言数据结构算法面试笔试题的相关知识点,包括链表数组、二叉树等常见数据结构的经典算法题目。我们将分析每个题目的解题思路、C语言实现及时间和空间复杂度,帮助读者在面试笔试中脱颖而出。

正文:

一、引言

数据结构算法是计算机科学与技术领域的基础知识,对于求职者来说,掌握数据结构算法是必备技能。在面试笔试中,数据结构算法题目占据了很大的比重。本文将针对C语言数据结构算法面试笔试题进行详细解析,帮助读者应对各种笔试题目。

二、链表相关题目

1. 链表中特定值节点的删除

题目:给定一个链表,删除链表中所有值为x的节点。

解题思路:遍历链表,使用while循环和if条件语句判断节点值,删除符合条件的节点。

C语言实现:

“`c

void deleteNode(ListNode* head, int x) {

ListNode* current = head;

ListNode* prev = NULL;

while (current != NULL) {

if (current->val == x) {

if (prev == NULL) {

head = current->next;

} else {

prev->next = current->next;

}

free(current);

current = prev->next;

} else {

prev = current;

current = current->next;

}

}

}

“`

时间复杂度:O(n),空间复杂度:O(1)

2. �链表最小值节点的删除

题目:给定一个链表,删除链表中的最小值节点。

解题思路:遍历链表,记录最小值节点的前驱和最小值节点,最后删除最小值节点。

C语言实现:

“`c

void deleteMinNode(ListNode* head) {

ListNode* current = head;

ListNode* prevMin = NULL;

ListNode* minNode = NULL;

while (current != NULL) {

if (minNode == NULL || current->val val) {

minNode = current;

prevMin = prev;

}

current = current->next;

}

if (prevMin == NULL) {

head = minNode->next;

} else {

prevMin->next = minNode->next;

}

free(minNode);

}

“`

时间复杂度:O(n),空间复杂度:O(1)

(注:以下题目类似,仅提供题目、解题思路和C语言实现,不再重复时间和空间复杂度分析)

3. 链表的头插法

题目:实现链表的头插法。

解题思路:创建新节点,插入到链表头部。

C语言实现:

“`c

void insertAtHead(ListNode** head, int x) {

ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));

newNode->val = x;

newNode->next = *head;

*head = newNode;

}

“`

4. 链表的尾插法

题目:实现链表的尾插法。

解题思路:创建新节点,插入到链表尾部。

C语言实现:

“`c

void insertAtTail(ListNode** head, int x) {

ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));

newNode->val = x;

newNode->next = NULL;

if (*head == NULL) {

*head = newNode;

} else {

ListNode* current = *head;

while (current->next != NULL) {

current = current->next;

}

current->next = newNode;

}

}

“`

5. 链表的逆置

题目:给定一个链表,实现链表的逆置。

解题思路:使用三个指针分别记录当前节点、前一个节点和后一个节点,实现链表的逆置。

C语言实现:

“`c

void reverseList(ListNode** head) {

ListNode* prev = NULL;

ListNode* current = *head;

ListNode* next = NULL;

while (current != NULL) {

next = current->next;

current->next = prev;

prev = current;

current = next;

}

*head = prev;

}

“`

6. 链表中特定区间元素的删除

题目:给定一个链表,删除链表中位于区间[a, b]内的所有元素。

解题思路:遍历链表,删除区间内的节点。

C语言实现:

“`c

void deleteRange(ListNode** head, int a, int b) {

ListNode* current = *head;

ListNode* prev = NULL;

while (current != NULL) {

if (current->val >= a && current->val <= b) {

if (prev == NULL) {

*head = current->next;

} else {

prev->next = current->next;

}

free(current);

current = prev->next;

} else {

prev = current;

current = current->next;

}

}

}

“`

7. 找出两个链表的公共节点

题目:给定两个链表,找出它们的公共节点。

解题思路:使用哈希表记录第一个链表的节点,遍历第二个链表,查找公共节点。

C语言实现:

“`c

ListNode* findCommonNode(ListNode* head1, ListNode* head2) {

HashSet set;

while (head1 != NULL) {

set.add(head1);

head1 = head1->next;

}

while (head2 != NULL) {

if (set.contains(head2)) {

return head2;

}

head2 = head2->next;

}

return NULL;

}

“`

8. 链表奇偶位序元素的分离

题目:给定一个链表,将奇数位序的元素和偶数位序的元素分离。

解题思路:分别使用两个链表存储奇数位序和偶数位序的元素,最后合并两个链表。

C语言实现:

“`c

void separateOddEven(ListNode** head) {

ListNode* oddHead = NULL;

ListNode* evenHead = NULL;

ListNode* oddTail = NULL;

ListNode* evenTail = NULL;

int index = 1;

while (*head != NULL) {

if (index % 2 == 1) {

if (oddTail == NULL) {

oddHead = oddTail = *head;

} else {

oddTail->next = *head;

oddTail = oddTail->next;

}

} else {

if (evenTail == NULL) {

evenHead = evenTail = *head;

} else {

evenTail->next = *head;

evenTail = evenTail->next;

}

}

*head = (*head)->next;

index++;

}

if (oddTail != NULL) {

oddTail->next = evenHead;

}

*head = oddHead;

}

“`

9. 链表奇偶位序元素的分离,一个头插一个尾插

题目:给定一个链表,将奇数位序的元素和偶数位序的元素分离,奇数位序元素使用头插法,偶数位序元素使用尾插法。

解题思路:分别使用头插法和尾插法处理奇数位序和偶数位序的元素。

C语言实现:

“`c

void separateOddEvenWithInsert(ListNode** head) {

ListNode* oddHead = NULL;

ListNode* evenHead = NULL;

ListNode* oddTail = NULL;

ListNode* evenTail = NULL;

int index = 1;

while (*head != NULL) {

if (index % 2 == 1) {

insertAtHead(&oddHead, (*head)->val);

} else {

insertAtTail(&evenHead, (*head)->val);

}

*head = (*head)->next;

index++;

}

oddTail = oddHead;

while (oddTail != NULL && oddTail->next != NULL) {

oddTail = oddTail->next;

}

if (oddTail != NULL) {

oddTail->next = evenHead;

}

*head = oddHead;

}

“`

10. 链表的去重

题目:给定一个链表,删除链表中重复的节点。

解题思路:使用哈希表记录已遍历的节点,删除重复节点。

C语言实现:

“`c

void deleteDuplicates(ListNode** head) {

HashSet set;

ListNode* current = *head;

ListNode* prev = NULL;

while (current != NULL) {

if (set.contains(current->val)) {

prev->next = current->next;

free(current);

current = prev->next;

} else {

set.add(current->val);

prev = current;

current = current->next;

}

}

}

“`

三、数组相关题目

1. 数组元素的倒置

题目:给定一个数组,实现数组元素的倒置。

解题思路:使用双指针法,一个指针指向数组头部,另一个指针指向数组尾部,交换两个指针指向的元素,然后移动指针,直到两个指针相遇。

C语言实现:

“`c

void reverseArray(int* arr, int size) {

int left = 0;

int right = size – 1;

while (left < right) {

int temp = arr[left];

arr[left] = arr[right];

arr[right] = temp;

left++;

right–;

}

}

“`

2. 数组中特定值元素的删除

题目:给定一个数组,删除数组中所有值为x的元素。

解题思路:使用双指针法,一个指针用于遍历数组,另一个指针用于指向下一个插入位置。遍历数组时,如果当前元素不等于x,则将其复制到下一个插入位置。

C语言实现:

“`c

int removeElement(int* arr, int size, int x) {

int i = 0;

for (int j = 0; j < size; j++) {

if (arr[j] != x) {

arr[i++] = arr[j];

}

}

return i;

}

“`

3. 数组中值位于某一区间的元素的删除

题目:给定一个数组,删除数组中值位于区间[a, b]内的所有元素。

解题思路:使用双指针法,一个指针用于遍历数组,另一个指针用于指向下一个插入位置。遍历数组时,如果当前元素不在区间[a, b]内,则将其复制到下一个插入位置。

C语言实现:

“`c

int removeRange(int* arr, int size, int a, int b) {

int i = 0;

for (int j = 0; j < size; j++) {

if (arr[j] b) {

arr[i++] = arr[j];

}

}

return i;

}

“`

4. 数组的去重

题目:给定一个数组,删除数组中的重复元素。

解题思路:首先对数组进行排序,然后使用双指针法删除重复元素。

C语言实现:

“`c

int removeDuplicates(int* arr, int size) {

if (size == 0) return 0;

qsort(arr, size, sizeof(int), compare);

int i = 0;

for (int j = 1; j < size; j++) {

if (arr[j] != arr[i]) {

i++;

arr[i] = arr[j];

}

}

return i + 1;

}

“`

5. 数组中两个子数组的位置互换

题目:给定一个数组,将数组中前k个元素和后k个元素的位置互换。

解题思路:使用双指针法,一个指针指向前k个元素的尾部,另一个指针指向后k个元素的开头,交换两个指针指向的元素,然后移动指针,直到完成k次交换。

C语言实现:

“`c

void swapSubarrays(int* arr, int size, int k) {

int left = k – 1;

int right = size – k;

while (left >= 0 && right < size) {

int temp = arr[left];

arr[left] = arr[right];

arr[right] = temp;

left–;

right++;

}

}

“`

6. 数组元素的循环移动

题目:给定一个数组,将数组中的元素循环移动k个位置。

解题思路:先将数组分为两部分,然后将这两部分逆置,最后将整个数组逆置。

C语言实现:

“`c 𝐚𝗂𝑥𝗭𝓩𝑆.𝐜𝕠𝘮

void rotateArray(int* arr, int size, int k) {

k %= size;

reverseArray(arr, k);

reverseArray(arr + k, size – k);

reverseArray(arr, size);

}

“`

四、二叉树相关题目

1. 根据后序遍历和中序遍历序列构造二叉树

题目:给定一棵二叉树的后序遍历序列和中序遍历序列,构造该二叉树。

解题思路:后序遍历的最后一个元素为根节点,在中序遍历中找到根节点的位置,将中序遍历序列分为左子树和右子树两部分,递归构造左右子树。

C语言实现:

“`c

TreeNode* buildTree(vector& inorder, vector& postorder) {

if (inorder.empty() || postorder.empty()) return NULL;

int rootVal = postorder.back();

TreeNode* root = new TreeNode(rootVal);

int rootIndex = find(inorder.begin(), inorder.end(), rootVal) – inorder.begin();

vector leftInorder(inorder.begin(), inorder.begin() + rootIndex);

vector rightInorder(inorder.begin() + rootIndex + 1, inorder.end());

vector leftPostorder(postorder.begin(), postorder.begin() + rootIndex);

vector rightPostorder(postorder.begin() + rootIndex, postorder.end() – 1);

root->left = buildTree(leftInorder, leftPostorder);

root->right = buildTree(rightInorder, rightPostorder);

return root;

}

“`

2. 求二叉树第k层的节点个数

题目:给定一棵二叉树,求第k层的节点个数。

解题思路:使用递归方法,逐层向下计算到达指定层时返回1,从而累加得到该层的节点数。

C语言实现:

“`c

int getNodesAtKthLevel(TreeNode* root, int k) {

if (root == NULL || k <= 0) return 0;

if (k == 1) return 1;

return getNodesAtKthLevel(root->left, k – 1) + getNodesAtKthLevel(root->right, k – 1);

}

“`

3. 查找一个节点是否在二叉树中

题目:给定一棵二叉树和一个节点值x,查找x是否在二叉树中。

解题思路:使用递归遍历二叉树,若找到匹配节点则返回该节点指针,否则返回null。

C语言实现:

“`c

TreeNode* searchNode(TreeNode* root, int x) {

if (root == NULL) return NULL;

if (root->val == x) return root;

TreeNode* left = searchNode(root->left, x);

if (left != NULL) return left;

return searchNode(root->right, x);

}

“`

4. 求二叉树的节点个数

题目:给定一棵二叉树,求二叉树的节点个数。

解题思路:可以通过遍历方法或分治方法来进行计算,遍历方法通过递归计数,分治方法则是每个节点返回1,累加得到总数。

C语言实现:

“`c

int countNodes(TreeNode* root) {

if (root == NULL) return 0;

return 1 + countNodes(root->left) + countNodes(root->right);

}

“`

5. 求二叉树叶子节点的个数

题目:给定一棵二叉树,求二叉树叶子节点的个数。

解题思路:通过递归判断节点是否为叶子节点(无子节点),若是则计数1,累加所有叶子节点的计数得到总数。

C语言实现:

“`c

int countLeafNodes(TreeNode* root) {

if (root == NULL) return 0;

if (root->left == NULL && root->right == NULL) return 1;

return countLeafNodes(root->left) + countLeafNodes(root->right);

}

“`

6. 求树的深度

题目:给定一棵二叉树,求树的深度。

解题思路:通过递归比较左右子树的深度,返回最大深度加1来得到树的深度。

C语言实现:

“`c

int getDepth(TreeNode* root) {

if (root == NULL) return 0;

int leftDepth = getDepth(root->left);

int rightDepth = getDepth(root->right);

return max(leftDepth, rightDepth) + 1;

}

“`

7. 判断一棵树是否为完全二叉树

题目:给定一棵二叉树,判断是否为完全二叉树。

解题思路:使用队列依次检查树的节点,确保所有非空节点都在空节点之前,若发现空节点后还有非空节点,则不是完全二叉树。

C语言实现:

“`c

bool isCompleteBinaryTree(TreeNode* root) {

if (root == NULL) return true;

queue q;

q.push(root);

bool mustBeLeaf = false;

while (!q.empty()) {

TreeNode* node = q.front();

q.pop();

if (node == NULL) mustBeLeaf = true;

else {

if (mustBeLeaf) return false;

q.push(node->left);

q.push(node->right);

}

}

return true;

}

“`

五、总结

本文详细介绍了C语言数据结构算法面试笔试题的相关知识点,包括链表、数组、二叉树等常见数据结构的经典算法题目。通过对每个题目的解题思路、C语言实现及时间和空间复杂度的分析,帮助读者在面试笔试中更好地应对各种题目。掌握这些算法题目,将为求职者增加竞争力,提高通过面试笔试的概率。在实际面试中,还需灵活运用所学知识,结合具体问题进行解答。祝大家面试顺利,求职成功!

AI写作助手 原创著作权作品,未经授权转载,侵权必究!文章网址:https://www.aixzzs.com/list/20832.html

AI写作工具

文章自动写作
输入您的写作要求,AI自动创作一篇高质量的原创文章。

开始创作

工作汇报总结
输入行业、岗位信息,AI助你写报告、总结、计划、体会。

开始创作

相关推荐

  • 真实的求职信写作_如何写求职信

    标题:真实的求职信写作——如何写求职信 在求职过程中,一份出色的求职信往往能让你在众多求职者中脱颖而出,成为招聘者的重点关注对象。那么,如何写一份真实、有针对性的求职信呢?以下是一…

    2024-11-23
  • 数控技术求职信_如何写求职信

    数控技术求职信:如何写求职信 在当今社会,求职已经成为每个人人生中不可或缺的一个环节。一份优秀的求职信能让你在众多求职者中脱颖而出,得到面试的机会。那么,如何写一份数控技术专业的求…

    2024-10-21
  • 求职信的概念_如何写求职信

    标题:求职信的概念与撰写技巧 在求职过程中,一份出色的求职信往往能够帮助你脱颖而出,给招聘者留下深刻的印象。那么,什么是求职信?如何撰写一份高质量的求职信呢?本文将从求职信的概念和…

    2024-11-20
  • 个人职业生涯目标范例规划书范文

    标题:个人职业生涯目标范例规划书范文 一、引言 随着社会的快速发展,个人职业生涯规划越来越受到人们的关注。一个明确的职业生涯规划,能帮助我们在职场中找到自己的定位,实现人生价值。本…

    2024-11-06
  • 个性化的电子简历_网申技巧

    标题:个性化的电子简历:打造网申高手的秘密武器 随着互联网技术的飞速发展,越来越多的企业开始采用网络招聘的方式选拔人才。在这个背景下,电子简历成为了求职者展示自我、争取面试机会的重…

    2024-10-28
  • 琴行创业计划书的模板

    标题:琴行创业计划书模板 一、前言 本计划书旨在详细阐述琴行创业的筹备、运营、管理与未来发展策略,为创业者提供一份全面、实用的创业指南。以下为琴行创业计划书的模板,可根据实际情况进…

    2024-11-17
  • 毕业生自荐书模板精选集_自荐书

    标题:毕业生自荐书模板精选集——开启职场之门的金钥匙 随着毕业季的临近,广大毕业生们即将告别校园,踏上职场的新征程。在这个关键的转折点上,一份优秀的自荐书显得尤为重要。它不仅是你展…

    2024-11-01
  • 工程造价专业自荐书_自荐书

    **工程造价专业自荐书** 尊敬的领导: 您好! 首先,感谢您在百忙之中抽出宝贵时间阅读我的自荐书。我叫XXX,现年22岁,来自陕西省,是XX大学工程造价专业201XX届的应届毕业…

    2024-11-08
  • 面试为何杳无音讯?_如何写求职信

    **面试为何杳无音讯?——求职信写作全攻略** 在求职过程中,面试后的等待往往是最令人焦虑的环节。许多求职者投递了简历、参加了面试,却迟迟等不到录用通知,甚至杳无音讯。这种情况究竟…

    2024-11-10
  • 两分钟自我介绍范文

    **两分钟自我介绍范文:展现真实自我,开启无限可能** 在快节奏的现代生活中,两分钟的时间或许微不足道,但在某些关键时刻,这两分钟却能成为我们展示自我、赢得机会的宝贵窗口。自我介绍…

    2024-10-29