✰✰✰数据结构代码题必会解题思路及举例

链表的解题思路与流程:

1. 定义链表节点的结构体,包括节点值和指向下一个节点的指针。
   ```c
   struct ListNode {
       int val;
       struct ListNode* next;
   };
   ```

2. 创建链表对象,可以使用循环或递归方式。可以根据具体问题的需求来决定创建链表的方式。

3. 链表的基本操作包括插入节点、删除节点和查找节点。

   - 插入节点:创建新节点并将其指针指向前一个节点,将前一个节点的指针指向新节点,将新节点的指针指向下一个节点即可。

     ```c
     void insertNode(struct ListNode* node, int value) {
         struct ListNode* new_node = (struct ListNode*)malloc(sizeof(struct ListNode));
         new_node->val = value;
         new_node->next = node->next;
         node->next = new_node;
     }
     ```

   - 删除节点:找到要删除的节点的前一个节点,将其指针指向要删除节点的下一个节点,然后释放要删除的节点。

     ```c
     struct ListNode* deleteNode(struct ListNode* head, int target) {
         if (head && head->val == target) {
             struct ListNode* new_head = head->next;
             free(head);
             return new_head;
         }
         struct ListNode* node = head;
         while (node->next) {
             if (node->next->val == target) {
                 struct ListNode* temp = node->next;
                 node->next = node->next->next;
                 free(temp);
                 break;
             }
             node = node->next;
         }
         return head;
     }
     ```

   - 查找节点:从头节点开始遍历链表,比较每个节点的值与目标值,直到找到目标节点或到达链表末尾。

     ```c
     int findNode(struct ListNode* head, int target) {
         struct ListNode* node = head;
         while (node) {
             if (node->val == target) {
                 return 1;
             }
             node = node->next;
         }
         return 0;
     }
     ```

4. 链表的常见问题类型包括反转链表、合并链表、判断链表是否有环等。
   - 反转链表:使用三个指针分别指向当前节点、前一个节点和下一个节点,反转指针的指向即可。

     ```c
     struct ListNode* reverseList(struct ListNode* head) {
         struct ListNode *prev = NULL, *curr = head;
         while (curr) {
             struct ListNode* next_node = curr->next;
             curr->next = prev;
             prev = curr;
             curr = next_node;
         }
         return prev;
     }
     ```

   - 合并链表:使用两个指针分别指向两个链表的头节点,比较节点值大小,将较小的节点连接到新链表中,移动指针继续比较。

     ```c
     struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
         if (!l1)
             return l2;
         if (!l2)
             return l1;
         struct ListNode* new_head;
         if (l1->val < l2->val) {
             new_head = l1;
             new_head->next = mergeTwoLists(l1->next, l2);
         }
         else {
             new_head = l2;
             new_head->next = mergeTwoLists(l1, l2->next);
         }
         return new_head;
     }
     ```

   - 判断链表是否有环:使用快慢指针,快指针每次移动两步,慢指针每次移动一步,如果存在环,两个指针会在某一节点相遇。若快指针能到达链表末尾,则无环。

     ```c
     int hasCycle(struct ListNode* head) {
         if (!head || !head->next)
             return 0;
         struct ListNode* slow = head;
         struct ListNode* fast = head;
         while (fast && fast->next) {
             slow = slow->next;
             fast = fast->next->next;
             if (slow == fast)
                 return 1;
         }
         return 0;
     }
     ```

树的解题思路与流程:

1. 定义树节点的结构体,包括节点值和左右子节点的指针。
   ```c
   struct TreeNode {
       int val;
       struct TreeNode* left;
       struct TreeNode* right;
   };
   ```

2. 创建树对象,可以使用递归或迭代方式。可以根据具体问题的需求来决定创建树的方式。

3. 树的基本操作包括插入节点、删除节点和查找节点。

   - 插入节点:找到节点要插入的位置,创建新节点并将其挂载到对应位置的子节点上。

     ```c
     void insertNode(struct TreeNode** root, int value) {
         if (*root == NULL) {
             struct TreeNode* new_node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
             new_node->val = value;
             new_node->left = NULL;
             new_node->right = NULL;
             *root = new_node;
         }
         else if (value < (*root)->val) {
             insertNode(&(*root)->left, value);
         }
         else {
             insertNode(&(*root)->right, value);
         }
     }
     ```

   - 删除节点:分为三种情况处理:删除叶子节点、删除只有一个子节点的节点、删除有两个子节点的节点。具体操作可以是将子节点移动至删除节点的位置,然后释放删除节点。

     ```c
     struct TreeNode* deleteNode(struct TreeNode* root, int key) {
         if (root == NULL)
             return root;
         if (key < root->val)
             root->left = deleteNode(root->left, key);
         else if (key > root->val)
             root->right = deleteNode(root->right, key);
         else {
             if (root->left == NULL) {
                 struct TreeNode* temp = root->right;
                 free(root);
                 return temp;
             }
             else if (root->right == NULL) {
                 struct TreeNode* temp = root->left;
                 free(root);
                 return temp;
             }
             struct TreeNode* min_node = findMinNode(root->right);
             root->val = min_node->val;
             root->right = deleteNode(root->right, min_node->val);
         }
         return root;
     }

     struct TreeNode* findMinNode(struct TreeNode* root) {
         while (root && root->left)
             root = root->left;
         return root;
     }
     ```

   - 查找节点:从根节点开始递归或迭代遍历树,比较每个节点的值与目标值,直到找到目标节点或到达叶子节点。

     ```c
     struct TreeNode* findNode(struct TreeNode* root, int target) {
         if (root == NULL || root->val == target)
             return root;
         if (target < root->val)
             return findNode(root->left, target);
         else
             return findNode(root->right, target);
     }
     ```

4. 树的常见问题类型包括前序遍历、中序遍历、后序遍历、层序遍历等。
   - 前序遍历:先输出当前节点的值,再依次遍历左子树和右子树。

     ```c
     void preorderTraversal(struct TreeNode* root) {
         if (root) {
             printf("%d ", root->val);
             preorderTraversal(root->left);
             preorderTraversal(root->right);
         }
     }
     ```

   - 中序遍历:先遍历左子树,再输出当前节点的值,最后遍历右子树。

     ```c
     void inorderTraversal(struct TreeNode* root) {
         if (root) {
             inorderTraversal(root->left);
             printf("%d ", root->val);
             inorderTraversal(root->right);
         }
     }
     ```

   - 后序遍历:先遍历左子树,再遍历右子树,最后输出当前节点的值。

     ```c
     void postorderTraversal(struct TreeNode* root) {
         if (root) {
             postorderTraversal(root->left);
             postorderTraversal(root->right);
             printf("%d ", root->val);
         }
     }
     ```

   - 层序遍历:按层次从上到下、从左到右的顺序遍历树,使用队列来实现。

     ```c
     void levelOrder(struct TreeNode* root) {
         if (root == NULL)
             return;
         struct TreeNode* queue[1000];
         int front = 0, rear = 0;
         queue[rear] = root;
         rear++;
         while (front < rear) {
             struct TreeNode* node = queue[front];
             front++;
             printf("%d ", node->val);
             if (node->left) {
                 queue[rear] = node->left;
                 rear++;
             }
             if (node->right) {
                 queue[rear] = node->right;
                 rear++;
             }
         }
     }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值