参考:1.数据结构C语言版|第2版;2.力扣;3.2025年数据结构考研复习指导。三个参考分别依次对应文章三个部分。
数据是客观事物的符号表示,是所有能输入到计算机中并被计算机程序处理的符号的总称。数据元素是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。数据项是组成数据元素的、有独立含义的、不可分割的最小单位。数据对象是性质相同的数据元素的集合,是数据的一个子集。数据结构是相互之间存在一种或多种特定关系的数据元素的集合。数据结构包括逻辑结构和存储结构两个层次,逻辑结构包括线性结构和非线性结构两个层次,线性结构包括一般线性表、受限线性表和推广线性表三个层次,非线性结构包括集合、树和图三个层次,存储结构包括顺序存储、链式存储、索引存储和散列存储四个层次。数据类型是一个值的集合和定义在这个值集上的一组操作的总称。抽象数据类型一般指由用户定义的、表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称,具体包括三部分:数据对象,数据对象上关系的集合以及对数据对象的基本操作的集合。
算法是为了解决某类问题而规定的一个有限长的操作序列。一个算法必须满足以下五个重要特性:有穷性、确定性、可行性、输入和输出。一个算法的优劣应该从以下几方面来评价:正确性、可读性、健壮性和高效性。 高效性包括时间和空间两个方面。问题规模。语句频度。渐进时间复杂度简称时间复杂度。最好时间复杂度。最坏时间复杂度。平均时间复杂度。渐进空间复杂度简称空间复杂度。
线性表的定义:由 n ( n ≥ 0 ) n(n\geq0) n(n≥0)个数据特性相同的元素构成的有限序列。
线性表的特点: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;
}
/**
* 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;
}
};
真题里面没叫删除,就叫你查询就好了。
/**
* 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;
}
};
/**
* 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;
}
};
/**
* 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;
}
};
真题里面不是相邻结点而是交错交换前后所有结点
/**
* 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;
}
};
/**
* 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;
}
};
/**
* 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;
}
};
/**
* 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;
}
};
/**
* 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;
}
};
太简单了,不想做了。
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};
}
};
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;
}
};
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;
}
};
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不用鸟它,都挺傻逼。