第一章节 绪论以及第二章节 线性表

参考:1.数据结构C语言版|第2版;2.力扣;3.2025年数据结构考研复习指导。三个参考分别依次对应文章三个部分。

文章目录

  • 第一章节
    • 知识点1
    • 知识点2
  • 第二章节
    • 第一部分
      • 基本概念
      • 线性表的顺序表示和实现
      • 线性表的链式表示和实现
    • 第二部分
      • 链表
        • 2. 两数相加
        • 19. 删除链表的倒数第 N 个结点(2009统考真题)
        • 21. 合并两个有序链表
        • 23. 合并K个升序链表
        • 24. 两两交换链表中的节点(2019统考真题)
        • 25. K 个一组翻转链表
        • 61. 旋转链表
        • 83. 删除排序链表中的重复元素
        • 82. 删除排序链表中的重复元素 II
      • n数之和
        • 1. 两数之和
        • 15. 三数之和
        • 18. 四数之和
      • 4. 寻找两个正序数组的中位数(2011统考真题)
    • 第三部分

第一章节

知识点1

数据是客观事物的符号表示,是所有能输入到计算机中并被计算机程序处理的符号的总称。数据元素是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。数据项是组成数据元素的、有独立含义的、不可分割的最小单位。数据对象是性质相同的数据元素的集合,是数据的一个子集。数据结构是相互之间存在一种或多种特定关系的数据元素的集合。数据结构包括逻辑结构和存储结构两个层次,逻辑结构包括线性结构和非线性结构两个层次,线性结构包括一般线性表、受限线性表和推广线性表三个层次,非线性结构包括集合、树和图三个层次,存储结构包括顺序存储、链式存储、索引存储和散列存储四个层次。数据类型是一个值的集合和定义在这个值集上的一组操作的总称。抽象数据类型一般指由用户定义的、表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称,具体包括三部分:数据对象,数据对象上关系的集合以及对数据对象的基本操作的集合。

知识点2

算法是为了解决某类问题而规定的一个有限长的操作序列。一个算法必须满足以下五个重要特性:有穷性、确定性、可行性、输入和输出。一个算法的优劣应该从以下几方面来评价:正确性、可读性、健壮性和高效性。 高效性包括时间和空间两个方面。问题规模。语句频度。渐进时间复杂度简称时间复杂度。最好时间复杂度。最坏时间复杂度。平均时间复杂度。渐进空间复杂度简称空间复杂度。

第二章节

第一部分

基本概念

线性表的定义:由 n ( n ≥ 0 ) n(n\geq0) n(n0)个数据特性相同的元素构成的有限序列。
线性表的特点:1.存在唯一的一个被称作”第一个“的数据元素.2存在唯一的一个被称作”最后一个“的数据元素3.除第一个之外,结构中的每个数据元素均只有一个前驱4.除最后一个之外,结构中的每个数据元素均只有一个后继。

线性表的顺序表示和实现

#include
using namespace std;
struct vector
{
    int maxsize;
    int * nums;
    int length;
};
void InitVector(vector & lb,int size)
{
    lb.maxsize=size;
    lb.nums=new int [size];
    lb.length=0;
}
void DestroyVector(vector & lb)
{
    lb.maxsize=-1;
    delete [] lb.nums;
    lb.length=-1;
}
void TraverseVector(vector & lb)
{
    for (int i=0;i<lb.length;i++)
    {
        cout<<lb.nums[i]<<" ";
    }
    cout<<endl;
}
int Find(vector & lb,int x)
{
    for (int i=0;i<lb.length;i++)
        if (lb.nums[i]==x)
            return i;
    return -1;
}
void Insert(vector & lb,int index,int value)
{
    if (lb.length==lb.maxsize) {cout<<"Vector has been full."<<endl;return;}
    for (int i=lb.length;i!=index;i--)
        lb.nums[i]=lb.nums[i-1];
    lb.nums[index]=value;
    lb.length+=1;
}
void Delete(vector & lb,int index)
{
    if (lb.length==0) {cout<<"Vector has been empty."<<endl;return;}
    for (int i=index;i<lb.length-1;i++)
        lb.nums[i]=lb.nums[i+1];
    lb.length-=1;
}
int main()
{
    vector lb;InitVector(lb,10);
    for (int i=0;i<9;i++)
    {
        lb.nums[i]=i+1;lb.length+=1;
    }
    TraverseVector(lb);
    cout<<lb.nums[0]<<" "<<lb.nums[8]<<endl;
    cout<<Find(lb,1)<<" "<<Find(lb,9)<<endl;
    Insert(lb,0,0);Insert(lb,lb.length,lb.nums[lb.length-1]+1);
    Delete(lb,0);Delete(lb,0);
    DestroyVector(lb);
    return 0;
}

线性表的链式表示和实现

一些概念理解一下。结点包括数据域、指针域。n个结点链结成为一个链表。单向链表。区分一下:头指针,头结点,首元结点。单向链表创建方法:前插法,后插法。循环链表。双向链表。

#include
using namespace std;
struct Node
{
    int data;
    Node * next;
};
void InitNode(Node * & node)
{
    node=new Node;node->next=nullptr;
}
void TraverseList(Node * & list)
{
    Node * temp=list;
    while (temp->next!=nullptr)
    {
        temp=temp->next;
        cout<<temp->data<<" ";
    }
    cout<<endl;
}
int Get(Node * & list,int index)
{
    Node * temp=list;
    for (int i=0;i<index+1;i++)
    {
        temp=temp->next;
        if (temp==nullptr) return -1;
    }
    return temp->data;
}
int Find(Node * & list,int value)
{
    Node * temp=list;int index=0;
    while (temp->next!=nullptr)
    {
        temp=temp->next;
        if (value==temp->data) return index;
        index+=1;
    }
    return -1;
}
void Insert(Node * & list,int index,int value)
{
    Node * temp1=list;
    for (int i=0;i<index;i++)
    {
        temp1=temp1->next;
        if (temp1->next==nullptr) break;
    }
    Node * temp2;InitNode(temp2);temp2->data=value;temp2->next=temp1->next;
    temp1->next=temp2;
}
void DestroyNode(Node * & node)
{
    node=nullptr;
}
void Delete(Node * & list,int index)
{
    Node * temp1=list;
    for (int i=0;i<index;i++)
    {
        temp1=temp1->next;
        if (temp1->next==nullptr) return;
    }
    if (temp1->next==nullptr) return;
    Node * temp2=temp1->next;
    temp1->next=temp2->next;
    DestroyNode(temp2);
}
void DestroyList(Node * & list)
{
    while (list->next!=nullptr)
    {
        Node * temp=list;
        list=list->next;
        DestroyNode(temp);
    }
}
int main()
{
    Node * list;InitNode(list);
    Node * temp=list;
    for (int i=0;i<10;i++)
    {
        InitNode(temp->next);temp=temp->next;temp->data=i;
    }
    TraverseList(list);
    cout<<Get(list,0)<<" "<<Get(list,9)<<endl;
    cout<<Find(list,0)<<" "<<Find(list,9)<<endl;
    for (int i=0;i<10;i++)
        Insert(list,0,i);
    TraverseList(list);
    for (int i=0;i<10;i++)
        Delete(list,0);
    TraverseList(list);
    DestroyList(list);
    return 0;
}

第二部分

链表

2. 两数相加
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode * result=l1;int x=0;
        while (l1 and l2)
        {
            l1->val+=l2->val+x;
            if (l1->val>=10)
            {
                l1->val%=10;x=1;
            }
            else x=0;
            if (!l1->next and l2->next)
            {
                l1->next=l2->next;l1=l1->next;break;
            }
            if (l1->next and !l2->next)
            {
                l1=l1->next;break;
            }
            if (!l1->next and !l2->next)
            {
                if (x) l1->next=new ListNode(1);
                return result;
            }
            l1=l1->next;l2=l2->next;
        }
        while (x)
        {
            l1->val+=1;
            if (l1->val==10) l1->val=0;
            else break;
            if (!l1->next)
            {
                l1->next=new ListNode(1);
                return result;
            }
            l1=l1->next;
        }
        return result;
    }
};
19. 删除链表的倒数第 N 个结点(2009统考真题)

真题里面没叫删除,就叫你查询就好了。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int length=0;ListNode * temp;
        temp=head;
        while (temp)
        {
            length+=1;temp=temp->next;
        }
        if (n==length) return head->next;
        temp=head;
        for (int i=0;i<length-n-1;i++)
            temp=temp->next;
        temp->next=temp->next->next;
        return head;
    }
};
21. 合并两个有序链表
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if (!list1) return list2;
        if (!list2) return list1;
        ListNode * result;
        if (list1->val<list2->val) {result=list1;list1=list1->next;}
        else {result=list2;list2=list2->next;}
        ListNode * temp=result;
        while (list1 and list2)
            if (list1->val<list2->val)
            {
                temp->next=list1;temp=temp->next;
                list1=list1->next;
            }
            else
            {
                temp->next=list2;temp=temp->next;
                list2=list2->next;
            }
        if (!list1) temp->next=list2;
        if (!list2) temp->next=list1;
        return result;
    }
};
23. 合并K个升序链表
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode * result=new ListNode;
        ListNode * temp1=result;
        while (1)
        {
            int i=0;
            for (;i<lists.size();i++)
                if (lists[i]) break;
            if (i==lists.size()) break;
            ListNode * temp2=lists[i];
            for (int j=i+1;j<lists.size();j++)
                if (lists[j] and lists[j]->val<temp2->val)
                {
                    temp2=lists[j];i=j;
                }
            temp1->next=temp2;temp1=temp1->next;
            lists[i]=lists[i]->next;
        }
        return result->next;
    }
};
24. 两两交换链表中的节点(2019统考真题)

真题里面不是相邻结点而是交错交换前后所有结点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if (!head) return head;
        ListNode * result=new ListNode;result->next=head;
        ListNode * node1=result;
        ListNode * node2=head;
        while (node1 and node2)
        {
            if (!node2->next) break;
            node1->next=node2->next;
            node2->next=node1->next->next;
            node1->next->next=node2;
            node1=node2;node2=node2->next;
        }
        return result->next;
    }
};
25. K 个一组翻转链表
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode * result=new ListNode;
        ListNode * temp=result;
        while (1)
        {
            int i=0;
            stack<ListNode *> my_stack;
            for (;i<k;i++)
                if (head)
                {
                    my_stack.push(head);head=head->next;
                }
                else break;
            if (i!=k)
            {
                temp->next=nullptr;
                while (!my_stack.empty())
                {
                    ListNode * top=my_stack.top();
                    my_stack.pop();
                    if (my_stack.empty())
                        temp->next=top;
                }
                break;
            }
            while (!my_stack.empty())
            {
                temp->next=my_stack.top();
                temp=temp->next;
                my_stack.pop();
            }
        }
        return result->next;
    }
};
61. 旋转链表
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if (!head) return head;
        ListNode * temp=head;int length=1;
        while (temp->next)
        {
            temp=temp->next;length+=1;
        }
        temp->next=head;k%=length;
        for (int i=0;i<length-k-1;i++)
            head=head->next;
        temp=head->next;head->next=nullptr;
        return temp;
    }
};
83. 删除排序链表中的重复元素
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode * temp=head;
        while (temp and temp->next)
        {
            if (temp->val==temp->next->val)
                temp->next=temp->next->next;
            else temp=temp->next;
        }
        return head;
    }
};
82. 删除排序链表中的重复元素 II
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode * result=new ListNode;
        ListNode * temp=result;
        int x=1;
        while (head)
        {
            if (x)
            {
                if (!head->next) temp->next=head;
                else if (head->val!=head->next->val)
                {
                    temp->next=head;temp=temp->next;
                    head=head->next;
                    temp->next=nullptr;
                    continue;
                }
                else x=0;
            }
            else if (head->next and head->val!=head->next->val)
                x=1;
            head=head->next;
        }
        return result->next;
    }
};

太简单了,不想做了。

n数之和

1. 两数之和
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> jh;
        for (int i=0;i<nums.size();i++)
        {
            if (jh.find(target-nums[i])!=jh.end())
                return {jh[target-nums[i]],i};
            jh[nums[i]]=i;
        }
        return {-1,-1};
    }
};
15. 三数之和
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
        for (int i=0;i<nums.size()-2;i++)
        {
            if (nums[i]>0) break;
            if (i>0 and nums[i]==nums[i-1]) continue;
            int zz1=i+1,zz2=nums.size()-1;
            while (zz1<zz2)
            {
                if (zz1>i+1 and nums[zz1]==nums[zz1-1]) {zz1+=1;continue;}
                if (zz2<nums.size()-1 and nums[zz2]==nums[zz2+1]) {zz2-=1;continue;}
                if (nums[i]+nums[zz1]+nums[zz2]>0) zz2-=1;
                else if (nums[i]+nums[zz1]+nums[zz2]<0) zz1+=1;
                else {result.push_back({nums[i],nums[zz1],nums[zz2]});zz1+=1;zz2-=1;}
            }
        }
        return result;
    }
};
18. 四数之和
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
        int n=nums.size();
        for (int i=0;i<n-3;i++)
        {
            if ((long) nums[i]>target and nums[i]>0) break;
            if (i>0 and nums[i]==nums[i-1]) continue;
            for (int j=i+1;j<n-2;j++)
            {
                if ((long) nums[i]+nums[j]>target and nums[j]>0) break;
                if (j>i+1 and nums[j]==nums[j-1]) continue;
                int l=j+1,r=n-1;
                while (l<r)
                {
                    if (l>j+1 and nums[l]==nums[l-1]) {l+=1;continue;}
                    if (r<n-1 and nums[r]==nums[r+1]) {r-=1;continue;}
                    if ((long) nums[i]+nums[j]+nums[l]+nums[r]>target) r-=1;
                    else if ((long) nums[i]+nums[j]+nums[l]+nums[r]<target) l+=1;
                    else {result.push_back({nums[i],nums[j],nums[l],nums[r]}),r-=1,l+=1;}
                }
            }
        }
        return result;
    }
};

4. 寻找两个正序数组的中位数(2011统考真题)

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int length=nums1.size()+nums2.size();
        if (length%2==1) return get(nums1,nums2,(length+1)/2);
        return (get(nums1,nums2,length/2)+get(nums1,nums2,length/2+1))/2;
    }
    double get(const vector<int> & nums1,const vector<int> & nums2,int k)
    {
        int m=nums1.size(),n=nums2.size();
        int index1=0,index2=0;
        while (1)
        {
            if (index1==m) return nums2[index2+k-1];
            if (index2==n) return nums1[index1+k-1];
            if (k==1) return min(nums1[index1],nums2[index2]);
            int newindex1=min(index1+k/2-1,m-1),pivot1=nums1[newindex1];;
            int newindex2=min(index2+k/2-1,n-1),pivot2=nums2[newindex2];;
            if (pivot1<pivot2)
            {
                k-=newindex1-index1+1;
                index1=newindex1+1;
            }
            else
            {
                k-=newindex2-index2+1;
                index2=newindex2+1;
            }
        }
    }
};

第三部分

2.2.3:13题纯纯傻逼。41页25、26不用鸟它,都挺傻逼。

你可能感兴趣的:(数据结构,数据结构,算法,绪论,线性表,c++)