数据结构(代码总结)

一、栈 队列

链表

#include<iostream>
using namespace std;
template<class T>
class node{
	public:
		node<T> *next;
		T data;
		node(){
		}
		node(const T& item)
		{
			data=item;
			next=NULL;
		}
}; 

template<class T>
class line{
	node<T> *head,*rear;
	int size;
	node<T> *pre,*cur;
	int pos;
	public:
		line()
		{//附加头节点 
			head=pre=new node<T>();
			cur=rear=NULL;
		}
		~line()
		{
			while(head)
			{
				node<T> *p=head;
				head=head->next;
				delete p; 
			}
		}
		void insertAt( const T& item)
		{
			node<T> *p=new node<T>(item,NULL);
			p->next=cur;
			pre->next=p;
			cur=p;
			size++;
			if(!rear) rear=p;
		}
		void insertAfter( const T& item)
		{
			node<T> *p=new node<T> (item,NULL);
			if(!cur)
			{
				head->next=p;
				rear=p;
			}
			else
			{
				p->next=cur->next;
				cur->next=p;
				if(!p->next) rear=p;
			}
			size++;
			cur=p;
		}
		void deleteAt()
		{
			pre->next=cur->next;
			pos--;
		}
		void deleteAfter()
		{
			cur->next=cur->next->next;
		}
		
		
};
int main()
{
	line<int> L;
	
	return 0;
}

 栈类

#include<iostream>
using namespace std;
class stack{
	private:
		int *data;
		int data_top;
		int maxsize;
	public:
		stack(int sz)
		{
			data=new int [sz];
			maxsize=sz;
			data_top=-1;	
		};
		~stack()
		{
			delete data;
		};
		void push(int x);
		void pop();
		bool empty();
		bool full();
		int top();
		void clear();
	 
}; 

void stack::push(int x)
{
	data[++data_top]=x;
}
void stack::pop()
{
	data_top--;
}
bool stack::empty()
{
	return data_top==-1;
}
bool stack::full()
{
	return data_top==maxsize-1;
}
int stack::top()
{
	return data[data_top];
}
void stack::clear()
{
	data_top=-1;
}

int main()
{
	stack q(10);
	for(int i=1;i<=5;i++)
	{
		q.push(i);
	}
	for(int i=1;i<=5;i++)
	{
		cout<<q.top()<<endl;
		q.pop();
	}
	q.clear();
	q.push(10086);
	cout<<q.top();
	return 0;
}

栈链表实现

#include<iostream>
using namespace std;
template<class T>
class node{
	public:
		node<T> *next;
		T data;
		node(){
		}
		node(const T& item)
		{
			data=item;
			next=NULL;
		}
}; 

template<class T>
class stack{
	node<T> *head;
	int cnt;
	public:
		stack()
		{
			head=NULL;
			cnt=0;
		}
		~stack()
		{
			while(head)
			{
				node<T> *p=head;
				head=head->next;
				delete p; 
			}
		}
		void clear()
		{
			while(head)
			{
				node<T> *p=head;
				head=head->next;
				delete p; 
			}
		}
		void push( const T& item)
		{
			node<T> *p=new node<T>(item);
			p->next=head;
			head=p;
			cnt++;
		}
		void pop()
		{
			if(head!=NULL)
			{
				node<T> *p=head;
				head=head->next;
				delete p;
				cnt--;
			}
		}
		T top()
		{
			return head->data;
		}
		bool empty()
		{
			return head==NULL;
		}
		int size()
		{
			return cnt;
		}	
};
int main()
{
	stack<int> q;
	for(int i=1;i<=10;i++)
	{
		q.push(i);
	}
	
	cout<<q.top();
	
	q.pop();
	
	cout<<endl<<q.empty();
	cout<<endl<<q.size();
	
	q.clear();
	
	while(!q.empty())
	{
		cout<<endl<<q.top();
		q.pop();
	}
	
	
	return 0;
}

 队列类

#include<iostream>
using namespace std;

class  cQueue
{	
	private:
		int head, rear, maxSize;
		int *a;
	public:	
		cQueue(int sz);	
		~cQueue()	{delete a;}
		bool empty();
		bool full();
		int  size();
		void push(int x);
		int  front(); 
		void pop();//删除队头元素
};

cQueue::cQueue(int sz)
{	head = rear = 0;   maxSize = sz;  
	a = new int[sz]; 
}
bool cQueue::empty()
{	return head==rear; 
}
bool cQueue::full()
{ return head==(rear+1)%maxSize; 
}
int   cQueue::size()
{ return (rear - head + maxSize)%maxSize; 
}
void cQueue::push(int x)
{ a[rear++] = x; rear %= maxSize;  //cout<<size()<<endl;
}
int cQueue::front()
{ return a[head];	
}
void cQueue::pop()	
{ head++;	head %= maxSize;	
}


/*
//循环队列的正确性测试 
int main()
{	cQueue	q(100);
	
	for(int i=1; i<=15; i++)  //i<=15再测试一次 
		q.push(i);
	while(q.size())
	{	cout<<q.front()<<" ";
		q.pop();		
	}
	return 0;
 } 
*/
//求解舞伴问题 
int main()
{   int man, lady, m;   // 男士、女士的人数,舞曲数
    cQueue  qM(1000), qL(1000);     // 男士、女士队列
     
    cin>>man>>lady>>m;
    
    for(int i=1; i<=man; i++)   qM.push(i);
    for(int i=1; i<=lady; i++)  qL.push(i);
    
    for(int i=1; i<=m; i++)
    {   int a, b;
        a = qM.front();
        qM.pop();
        qM.push(a);
        b = qL.front();
        qL.pop();
        qL.push(b);
        cout<<a<<" "<<b<<endl;        
    }
    return 0;
}

队列链表实现

#include<iostream>
using namespace std;
template<class T>
class node{
	public:
		node<T> *next;
		T data;
		node(){
		}
		node(const T& item)
		{
			data=item;
			next=NULL;
		}
}; 

template<class T>
class queue{
	node<T> *head;
	node<T> *rear;
	int cnt;
	public:
		queue()
		{
			head=NULL;
			rear=NULL;
			cnt=0;
		}
		~queue()
		{
			while(head)
			{
				node<T> *p=head;
				head=head->next;
				delete p; 
			}
		}
		void clear()
		{
			while(head)
			{
				node<T> *p=head;
				head=head->next;
				delete p; 
			}
		}
		void push( const T& item)
		{
			node<T> *p=new node<T>(item);
			if (head==NULL)
			{
				head=rear=p;
				cnt++;
			 } 
			else
			{
				rear->next=p;
				rear=p;
				cnt++;
			}
			
		}
		void pop()
		{
			if(head!=NULL)
			{
				node<T> *p=head;
				head=head->next;
				delete p;
				cnt--;
			}
		}
		T top()
		{
			return head->data;
		}
		bool empty()
		{
			return head==NULL;
		}
		int size()
		{
			return cnt;
		}	
};
int main()
{
	queue<int> q;
	for(int i=1;i<=10;i++)
	{
		q.push(i);
	}
	
	cout<<q.top();
	
	q.pop();
	
	cout<<endl<<q.empty();
	cout<<endl<<q.size();
	
	q.clear();
	
	while(!q.empty())
	{
		cout<<endl<<q.top();
		q.pop();
	}
	
	
	return 0;
}

后缀表达式

#include<iostream>
#include<string>
using namespace std;
class stack{
	private:
		double *data;
		int data_top;
		int maxsize;
	public:
		stack(int sz)
		{
			data=new double [sz];
			maxsize=sz;
			data_top=-1;	
		};
		~stack()
		{
			delete data;
		};
		void push(double x);
		void pop();
		bool empty();
		bool full();
		double top();
		void clear();
	 
}; 

void stack::push(double x)
{
	data[++data_top]=x;
}
void stack::pop()
{
	data_top--;
}
bool stack::empty()
{
	return data_top==-1;
}
bool stack::full()
{
	return data_top==maxsize-1;
}
double stack::top()
{
	return data[data_top];
}
void stack::clear()
{
	data_top=-1;
}


int main()
{
	stack q(100);
	string buf;
	cin>>buf; 
	
	int i=0;
	
	while (buf[i])
	{
		double x,y;
		switch(buf[i]){
			case '+':
				 x=q.top();	q.pop();
				 y=q.top();	q.pop();
				q.push(x+y);
				break;
			case '-':
				 x=q.top();	q.pop();
				 y=q.top();	q.pop();
				q.push(y-x);
				break;
			case '*':
				 x=q.top();	q.pop();
				 y=q.top();	q.pop();
				q.push(x*y);
				break;
			case '/':
				 x=q.top();	q.pop();
				 y=q.top();	q.pop();
				q.push(y/x);
				break;
			default:
				q.push(double(buf[i]-'0'));
		}
		i++;
	}
	cout<<q.top()<<endl;
	return 0;
}

中缀表达式

//保持运算符栈中的栈顶运算符在运算符中保持最高的运算级 
#include<iostream>
#include<string>
using namespace std;
template<class T>
class stack{
	private:
		T *data;
		int data_top;
		int maxsize;
	public:
		stack(int sz)
		{
			data=new T [sz];
			maxsize=sz;
			data_top=-1;	
		};
		~stack()
		{
			delete data;
		};
		void push(T x);
		void pop();
		bool empty();
		bool full();
		T top();
		void clear();
	 
}; 
template<class T> 
void stack<T>::push(T x)
{
	data[++data_top]=x;
}

template<class T> 
void stack<T>::pop()
{
	data_top--;
}

template<class T> 
bool stack<T>::empty()
{
	return data_top==-1;
}

template<class T>
bool stack<T>::full()
{
	return data_top==maxsize-1;
}

template<class T>
T stack<T>::top()
{
	return data[data_top];
}

template<class T> 
void stack<T>::clear()
{
	data_top=-1;
}

void compute(stack<char>& a, stack<double>& b)
{
	char c=a.top();
	a.pop();
	double x=b.top();
	b.pop();
	double y=b.top();
	b.pop();
	switch (c)
	{
		case '+':
			b.push(x+y);
			break;
		case '-':
			b.push(y-x);
			break;
		case '*':
			b.push(x*y);
			break;
		case '/':
			b.push(y/x);
			break;
	}
}

int main()
{
	stack<char> opsk(100);
	stack<double> numsk(100);
	
	string s;
	cin>>s;
	int i=0;
	while(s[i])
	{
		if(s[i]>='0'&&s[i]<='9')
		{
			numsk.push(double(s[i]-'0'));
		}
		else if(opsk.empty()||s[i]=='(')
		{
			opsk.push(s[i]);
		}
		else if(s[i]==')')
		{
			while(opsk.top()!='(')
			{
				compute(opsk,numsk);
			}
			opsk.pop();
		}
		else if(s[i]=='*'||s[i]=='/')
		{
			while(opsk.top()=='*'||opsk.top()=='/')
				compute(opsk,numsk);
		
			opsk.push(s[i]);
		 } 
		else if(s[i]=='+'||s[i]=='-')
		{
			while(opsk.top()!='('&&!opsk.empty())
			{
				compute(opsk,numsk);
			}
			opsk.push(s[i]); 
		}
		i++;
	}
	
	while(!opsk.empty())
	{
		compute(opsk,numsk);
	}
	cout<<numsk.top()<<endl;
	return 0;
}

 中缀转后缀表达式

//保持运算符栈中的栈顶运算符在运算符中保持最高的运算级 
#include<iostream>
#include<string>
using namespace std;
template<class T>
class stack{
	private:
		T *data;
		int data_top;
		int maxsize;
	public:
		stack(int sz)
		{
			data=new T [sz];
			maxsize=sz;
			data_top=-1;	
		};
		~stack()
		{
			delete data;
		};
		void push(T x);
		void pop();
		bool empty();
		bool full();
		T top();
		void clear();
	 
}; 
template<class T> 
void stack<T>::push(T x)
{
	data[++data_top]=x;
}

template<class T> 
void stack<T>::pop()
{
	data_top--;
}

template<class T> 
bool stack<T>::empty()
{
	return data_top==-1;
}

template<class T>
bool stack<T>::full()
{
	return data_top==maxsize-1;
}

template<class T>
T stack<T>::top()
{
	return data[data_top];
}

template<class T> 
void stack<T>::clear()
{
	data_top=-1;
}
string a; 
void compute(stack<char>& b)
{
	char c=b.top();
	b.pop();
	a+=c;
}

int main()
{
	stack<char> opsk(100);
	
	string s;
	cin>>s;
	int i=0;
	while(s[i])
	{
		if(s[i]>='0'&&s[i]<='9')
		{
			a+=s[i];
		}
		else if(opsk.empty()||s[i]=='(')
		{
			opsk.push(s[i]);
		}
		else if(s[i]==')')
		{
			while(opsk.top()!='(')
			{
				compute(opsk);
			}
			opsk.pop();
		}
		else if(s[i]=='*'||s[i]=='/')
		{
			while(opsk.top()=='*'||opsk.top()=='/')
			compute(opsk);
			
			opsk.push(s[i]);
		 } 
		else if(s[i]=='+'||s[i]=='-')
		{
			while(opsk.top()!='('&&!opsk.empty())
			{
				compute(opsk);
			}
			opsk.push(s[i]); 
		}
		i++;
	}
	
	while(!opsk.empty())
	{
		compute(opsk);
	}
	cout<<a<<endl;
	return 0;
}

二、排序算法

插入排序

#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
int n;
int a[10000000];
template <class T> 
void  sort(T *a,int n)
{
	for(int i=0;i<n;i++)
	{
		T temp=a[i];
		int p=i;
		for(int j=i;j>=0;j--)
		{
			if(temp<a[j])
			{
				a[p]=a[j];
				p=j;
			}
			else
			{
				break;
			}
		}
		a[p]=temp;//如果是从i到0都没有比他大的在零号位就没有赋值,就会有问题,
		//所以应该写在最后
	}
}
int main()
{
	
	srand(time(0));
	double t=time(0);
	
	 
	cin>>n;
	for(int i=0;i<n;i++)
	{
		//cin>>a[i];
		a[i]=rand()%10000*rand()%10000;
	}
	sort(a,n);
	/*for(int i=0;i<n;i++)
	{
		cout<<a[i]<<" ";
	}*/
	cout<<time(0)-t;
	
	return 0;
}

 归并排序

#include<iostream>
using namespace std;
template <class T>
void TwoWayMerge(T Dst[],T Src[],int s,int e1,int e2)
{
	int s1,s2;
	for(s1=s,s2=e1+1;s1<=e1&&s2<=e2;)
	{
		if (Src[s1]<=Src[s2])
		{
			Dst[s++]=Src[s1++];
		}
		else
		{
			Dst[s++]=Src[s2++];
		}	
	}
	if(s1<=e1)
	{
		memcpy(&Dst[s],&Src[s1],(e1-s1+1)*sizeof(T));
	}
	else
	{
		memcpy(&Dst[s],&Src[s2],(e2-s2+1)*sizeof(T));
	}
}

template <class T>
void OnePassMerge(T Dst[],T Src[],int len,int n)
{
	int i;
	for(i=0;i+2*len<n;i+=2*len)
		TwoWayMerge(Dst,Src,i,i+len-1,i+2*len-1);
	if(i<n-len)
		TwoWayMerge(Dst,Src,i,i+len-1,n-1);
	else
		memcpy(&Dst[i],&Src[i],(n-i)*sizeof(T));
}


template <class T>
void Mergesort(T Src[],int n)
{
	T *dst=new T[n];
	int k=1;
	while(k<n)
	{
		OnePassMerge(dst,Src,k,n);
		k<<=1;
	
		if(k>=n)
		{
			memcpy(Src,dst,n*sizeof(T));
		}
		else
		{
			OnePassMerge(Src,dst,k,n);
			k<<=1;
		}
	}
	delete [] dst;
}


int main()
{
	int Src[8]={8,9,10,1,2,3,13,14};
	Mergesort(Src,8);
	for(int i=0;i<=7;i++)
	{
		cout<<Src[i]<<" ";
	}
	return 0;
	
 }

 基数排序

#include<iostream>
#include<queue>
using namespace std;

int maxdigit(int data[],int n)
{
	int d=1;//计算最高位数
	int p=10;//倍数
	for(int i=0;i<n;i++)
	{
		while(data[i] >= p)
		{
			p*=10;
			++d;
		}
	 } 
	 return d;
 } 
 
void radixsort(int data[],int n)
{
	int digits=maxdigit(data,n);
	queue<int> q[10];
	int d,factor;
	for(d=1,factor=1;d<=digits; factor*=10,d++)
	{
		for(int j=0;j<n;j++)
		{
			q[(data[j]/factor)%10].push(data[j]);
		}
		int j=0;
		for(int k=0;k<10;k++)
		{
			while(!q[k].empty())
			{
				data[j++]=q[k].front();
				q[k].pop();
			}
		}
	}
}

int main()
{
	int data[10] = {179, 208, 306, 93, 859, 984, 55, 9, 271, 33};
	radixsort(data, 10);

	cout << "排序后结果:" << endl;
	for (int i = 0; i < 10; i++)
		cout << data[i] << " ";
	return 0;
}

 快速排序

#include<iostream>
using namespace std;

int sort(int *a,int low,int high)
{
	if(low<high)
	{
		int i=low;
		int j=high;
		int key=a[i];
		while(i<j)
		{
			while(i<j&&a[j]>=key)
			{
				j--;
			}
			if(i<j)
			{
				a[i]=a[j];
				i++;
			}
			while(i<j&&a[i]<=key)
			{
				i++;
			}
			if(i<j)
			{
				a[j]=a[i];
				j--;
			}
		}
		a[i]=key;
		/*
		//测试
		cout<<key<<endl;
		for(int i=0;i<=6;i++)
		{
			cout<<a[i]<<" ";
		} 
		cout<<endl;*/
		sort(a,low,i-1);
		sort(a,i+1,high);
	}
} 
 
int main()
{
	int a[10]={5,8,99,44,55,1,-1};
	sort(a,0,6);
	for(int i=0;i<=6;i++)
	{
		cout<<a[i]<<" ";
	}
	return 0;
}

冒泡排序

#include<iostream>
using namespace std;
const int maxn=1e5+3;
int a[maxn];
int n;
template <class T>
void sort(T *a,int n)
{
	bool flag=true; 
	for(int i=0;i<n&&flag;i++)
	{
		flag=false;
		for(int j=i+1;j<n;j++)
		{
			int temp=a[i];
			if(a[i]>a[j])
			{
				flag=true;
				a[i]=a[j];
				a[j]=temp;
			}
		}
	}
}
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	 } 
	sort(a,n);
	for(int i=0;i<n;i++)
	{
		cout<<a[i]<<" ";
	}
	return 0;
}

树形选择排序

#include<bits/stdc++.h>
using namespace std;

//树形排序:从小到大
template<class T>
void treeSort(T* a, int n)
{	
#define Left(i)      (2*(i)-2*n)
#define Right(i)   (2*(i)-2*n+1)
#define Father(i)  (n+(i)/2)
#define Brother(i)  ((i)&1?(i)-1:(i)+1)
#define Root          (2*n-2)
#define min(a,b)      (a)<(b)?(a):(b)
#define INF_VALUE  0x3FFFFFFF

	T* t = new T(2*n-1);   
    memcpy(t, a, sizeof(T)*n);
	
	//第1轮选择
	for(int i=n; i<=Root; i++) 
    	t[i]= min(t[Left(i)],t[Right(i)]);   
	a[0]=t[Root];

	//第2轮至第n轮选择
	for(int k=1; k<=n-1; k++) 
	{   // 将上一轮的最小值修改为无穷大INF_VALUE。
	    // 沿着等于t[Root]的分枝向下直到叶结点t[sel]=t[Root]
		int sel=Root;
		int left=Left(sel);
		while(left>=0) // 判断sel是否为叶节点
		{   sel = (t[sel]==t[left]) ? left : (left+1);
			left=Left(sel);
		} 
		t[sel]=INF_VALUE;
		
		// 本轮选择:从叶往根从t[sel]往t[Root]选择最小值
		sel=Father(sel);
		while(sel<=Root)
		{   t[sel] = min(t[Left(sel)],t[Right(sel)]);
			sel = Father(sel);
		}
		a[k]=t[Root];
	}
	delete t;
}

int main()
{	
	int a[10]={0,45,723,23,3,45,5,8,9,12345};
	treeSort(a, 10);
	for(int i=0; i<10; i++)
		cout<<a[i]<<" ";
	return 0;
}

希尔排序

//希尔排序 

#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
const int maxn=1e7+3;
int a[maxn];
int n;

template <class T> 
void ShellSort(T A[ ], int n, int s) //s分组数量
{   int i,j,k;
    T temp;
    for(k=s; k>0; k>>=1)  //分组次数
        for(i=k; i<n; i++) 
        //对A[i]所在组的前面部分插入排序
        {   
			temp=A[i];  
			j=i-k;
            while(j>=0 && temp<A[j])
            //前面元素已经有序,第2个条件避免无效比较
            {   A[j+k]=A[j];   j-=k; }
            A[j+k]=temp;
        }
}

int main()
{
	
	srand(time(0));
	double t=time(0);
	
	 
	cin>>n;
	for(int i=0;i<n;i++)
	{
//		cin>>a[i];
		a[i]=rand()%10000*rand()%10000;
	}
	ShellSort(a,n,n/2);
	/*for(int i=0;i<n;i++)
	{
		cout<<a[i]<<" ";
	}*/
	cout<<time(0)-t;
	
	return 0;
}

二分查找优化插入排序

//递归二分方法优化插入排序 

#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
const int maxn=1e7+3;
int a[maxn];
int n;

int bins(int *a,int n,int l, int r,int i)//i为要插入的数据 
{
	if(l>r) return l;
	int m=(l+r)/2;
	if(a[i]<a[m])
		return bins(a,n,l,m-1,i);
	else 
		return bins(a,n,m+1,r,i);
}

void binssort(int *a,int n)
{
	int k;//k为要插入的位置
	for(int i=1;i<n;i++)
	{
		k=bins(a,n,0,i-1,i);
		int temp=a[i];
		for(int j=i;j>k;j--)
		{
			a[j]=a[j-1];	
		}	
		a[k]=temp;
	} 	
} 

void bbinssort(int *a,int n)
{
	int i, k, r;  
    for (i=1; i<n; i++)  //将a[i]插入a[0..i-1]
    {   int temp=a[i];    k=0;   r=i-1;
        while (k<=r)  //计算插入位置k
       {   int m=(k+r)/2;
            if (temp<a[m]) r=m-1; 
            else k=m+1; 
       }
       for (r=i; r>k; r--) //移动a[k..i-1]至a[k+1..i]
           a[r]=a[r-1];
       a[k]=temp;	      //完成插入    
    }
}

int main()
{
	
	srand(time(0));
	double t=time(0);
	
	//double t_clock=clock(); 
	cin>>n;
	for(int i=0;i<n;i++)
	{
//		cin>>a[i];
		a[i]=rand()%10000*rand()%10000;
	}
	bbinssort(a,n);
	/*for(int i=0;i<n;i++)
	{
		cout<<a[i]<<" ";
	}*/
	cout<<time(0)-t<<endl;
	//cout<<clock()-t_clock<<endl; 
	return 0;
}

三、查找算法

朴素查找

#include<bits/stdc++.h>
using namespace std;
char s[1000];
char p[1000];
int area[100];
int space;
void findarea(char* s,char *p)
{
	int m=strlen(p);
	int n=strlen(s);
	for(int i=1;m+i-2<=n-1;i++)
	{
		int vis=0;
		for(int j=0;j<m;j++)
		{
			if(s[i-1+j]!=p[j])
			{
				vis=1;
				break;
			}
		}
		if(vis==0)
		{
			area[++space]=i;
		}
	}
}
int main()
{
	cin>>s>>p;
	findarea(s,p);
	if(!space)
	{
		cout<<"没有匹配的";
		return 0; 
	}
	for(int i=1;i<=space;i++)
	{
		cout<<area[i]<<" "; 
	}
	return 0;
} 

分块查找

//分块查找  块间有序 块内无序  包含索引项 包括最大关键码值和块的起始地址 

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

// 定义每个块的大小
const int blockSize = 3;

// 分块查找算法
int blockSearch(vector<int>& arr, vector<int>& blocks, int target) {
    int n = arr.size();
    int m = blocks.size();

    // 先在块索引中查找
    int blockIndex = -1;
    for (int i = 0; i < m; i++) {
        if (blocks[i] >= target) {
            blockIndex = i;
            break;
        }
    }

    // 如果块索引中不存在,则返回-1
    if (blockIndex == -1) {
        return -1;
    }

    // 在对应的块中查找
    int start = blockIndex * blockSize;
    int end = min(start + blockSize, n);
    for (int i = start; i < end; i++) {
        if (arr[i] == target) {
            return i;
        }
    }

    // 如果块中不存在,则返回-1
    return -1;
}

int main() {
    vector<int> arr = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
    int n = arr.size();

    // 计算块的数量
    int m = ceil(sqrt(n));

    // 构建块索引
    vector<int> blocks(m);
    for (int i = 0; i < m; i++) {
        blocks[i] = arr[i * blockSize];
    }

    int target = 6;
    int index = blockSearch(arr, blocks, target);
    if (index != -1) {
        cout << "找到了,下标为:" << index << endl;
    } else {
        cout << "未找到" << endl;
    }

    return 0;
}

KMP算法


/*核心是next的求法,第0个数是-1 来控制j向后移动,第1个数是0 因为不会存在重复的字符子串 
之后的数是他前面的最大重复子串的长度*/ 

#include<iostream>
#include<cstring>
using namespace std;
int nextt[100];	
char T[1000], P[1000];

bool isSame(char *p, int s, int e)
//判断p[0: ]与p[s:e]是否相同 
{	for(int k=0,i=s; i<=e; k++,i++)
		if(p[k]!=p[i])	return 0; 
	return 1;
}

void genNext(char *p, int *nextt)
//用朴素方法求nextt[] 
{  	
	nextt[0] = -1;
	nextt[1] = 0;
	for(int i=2; i<strlen(p); i++)//cal nextt[i]
	{	
		nextt[i] = 0;
		for(int j=i-1; j>0; j--) //j: 相同前(后)缀的长度 
		{	
			if(isSame(p, i-j, i-1))	
			{	
				nextt[i] = j; 
				break;
			}
		}
		if(p[nextt[i]]==p[i])//优化 
		{
			nextt[i]=nextt[nextt[i]];
		} 
	}	
} 

int main()
{	
	cin>>P>>T;	
	genNext(P, nextt);//计算nextt[ ]	
	for(int i=0;i<strlen(P);i++)
	{
		cout<<nextt[i]<<" ";
	}
	cout<<endl;
	int	i, j; //i:模式串P的下标   j:母串T的下标	
	for(i=0, j=0; i<strlen(P) && j<strlen(T); )	
	{	
		if(P[i]==T[j])//匹配则继续比较下一个字符	
		{	
			i++;	
			j++;	  
		}		
		else if(nextt[i]>0)
		{
			i = nextt[i];
		} 
		else
		{
			i=0;
			j++;
		}
		
	}
	if(i>=strlen(P))	cout<<j-strlen(P)<<endl;//首次匹配位置 
		else		cout<<-1<<endl;
} 
//输入样例1:ababacb
//输出样例1:-1 0 0 1 2 3 0

//输入样例2:abcabcd
//输出样例2:-1 0 0 0 1 2 3

//输入样例3:abcabca
//输出样例3:-1 0 0 0 1 2 3

/*ABABC
ABABC ABABCABAA CAADB ABABCAADKDABC*/

KMP优化

#include<iostream>
#include<string>
using namespace std;
#define next nex
string P,T;
int next[1000];
void Next(const string &P,int *next)
{
	next[0]=-1;
	int j=0;
	int k=-1;
	while(j<P.length()-1)
	{
		/*	*/
		if(k==-1||P[j]==P[k])
		{
			j++;
			k++;
			next[j]=k;
		}
		/*next优化
		if (k==-1||P[j]==P[k])
		{
			j++;
			k++;
			if(P[j]==P[k])
			next[j]=next[k];
			else
			next[j]=k;
		}*/
		else
		{
			k=next[k];
		}
	} 
}
void KMP(const string &P,const string& S)//P是模式串 S是文本串 
{
	int i=0,j=0;
	Next(P,next);
	for(int i=0;i<P.size();i++)
	cout<<next[i]<<" ";
	cout<<endl;
	while(i<int(P.size())&&j<int (S.size()))//p.size()默认是unsigned类型  
	{
		if(i==-1||P[i]==S[j])
		{
			i++;
			j++;
		}
		else
		{
			i=next[i];
		}
		
		if(i==P.size())
		{
			cout<<j-P.size()<<"   ";
			i=next[i];
		}
	}
}
int main()
{
	cin>>P>>T;

	KMP(P,T);
	return 0;
}

/*
ABABC
ABABCABABCABAACAADBABABCAADKDABC
*/

四、树

#include<iostream>
#include<vector>
using namespace std;

void heapify(vector<int>& arr, int n, int i) {
	int largest = i;
	int l = 2 * i + 1;
	int r = 2 * i + 2;
	if (l < n && arr[l] > arr[largest]) {
		largest = l;
	}
	if (r < n && arr[r] > arr[largest]) {
		largest = r;
	}
	if (largest != i) {
		swap(arr[i], arr[largest]);
		heapify(arr, n, largest);
	}
}

void treeSelectionSort(vector<int>& arr) {
	int n = arr.size();
	for (int i = n / 2 - 1; i >= 0; i--) {
		heapify(arr, n, i);
	}
	for (int i = n - 1; i > 0; i--) {
		swap(arr[0], arr[i]);
		heapify(arr, i, 0);
	}
}

int main()
{
	vector<int>a;
	a={1,2,5,9,55};
	treeSelectionSort(a);
	for(int i=0;i<5;i++)
	{
		cout<<a[i]<<" ";
	}
	return 0;
} 

二叉树

#include<iostream>
using namespace std;
struct node{
	int data;
	node * pl,*pr;
}tree[20000];
int n;

int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		int a,l,r;
		cin>>a>>l>>r;
		tree[a].data=a;
		if(!l)	tree[a].pl=NULL;
		else	tree[a].pl=&tree[l];
		if(!r)	tree[a].pr=NULL;
		else	tree[a].pr=&tree[r];
	}
	
	node *p=&tree[1];
	while(p)
	{
		cout<<p->data<<" ";
		if(p->pl!=NULL)
		{
			p=p->pl;
		}
		else
		{
			p=p->pr;
		}
	}
	
	return 0;
	
 } 

二叉树前中后序遍历

#include<iostream>
using namespace std;
struct node{
	char data;
	node * pl,*pr;
}tree[20000];
int n;

void preorder(node *t)
{
	if(!t) return ;
	cout<<t->data<<" ";
	preorder(t->pl);
	preorder(t->pr);
 } 
void inorder(node *t)
{
	if(!t) return ;
	inorder(t->pl);
	cout<<t->data<<" ";
	inorder(t->pr);
}
void endorder(node *t)
{
	if(!t) return ;
	endorder(t->pl);
	endorder(t->pr);
	cout<<t->data<<" ";
}

int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		int l,r,idex;
		char a;
		cin>>idex>>a>>l>>r;
		tree[idex].data=a;
		if(!l)	tree[idex].pl=NULL;
		else	tree[idex].pl=&tree[l];
		if(!r)	tree[idex].pr=NULL;
		else	tree[idex].pr=&tree[r];
	}
	cout<<"前序遍历:  "; 
	preorder(&tree[1]);cout<<endl;
	cout<<"中序遍历:  "; 
	inorder(&tree[1]);cout<<endl;
	cout<<"后序遍历:  "; 
	endorder(&tree[1]);cout<<endl;
	return 0;
	
 } 

二叉树层序遍历

#include<iostream>
#include<queue> 
using namespace std;
struct node{
	char data;
	node * pl,*pr;
}tree[20000];
int n;
queue<node*>q;

int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		int l,r,idex;
		char a;
		cin>>idex>>a>>l>>r;
		tree[idex].data=a;
		if(!l)	tree[idex].pl=NULL;
		else	tree[idex].pl=&tree[l];
		if(!r)	tree[idex].pr=NULL;
		else	tree[idex].pr=&tree[r];
	}
	
	node *p=&tree[1];
	q.push(p);
	while(!q.empty())
	{
		node *p=q.front();
		cout<<p->data<<" ";
		if(p->pl)
		q.push(p->pl);
		if(p->pr)
		q.push(p->pr);
		q.pop();	 
	}
	
	return 0;
	
 } 
 /* 4
 1  A 2 3
 2 B 0 5
 3 C 0 0
 5 E 0 0 */

二叉排序树

//二叉排序树 左子树都小于根 右子树都大于根   新插入的节点一定是叶子节点
//删除操作  如果进行直接替换 ,替换的前驱(后继)不一定是叶子节点,可能有左子树(右子树) 
//			如果是让后继变为前驱的右子树(前驱变为后继的左子树)要判断P的父节点是不是根节点 

#include<iostream>
using namespace std;

template <class T>
class tNode {
public:
	tNode<T>* left;
	tNode<T>* right;
	T data;
	
};


template <class T>
void freeTree(tNode<T>* root)
{
	if(root)
	{
		freeTree(root->left);
		freeTree(root->right);
		delete root;
	}
 } 
template <class T>
void insert(tNode<int>*& root, T x)
{
	if (!root)
	{
		root = new tNode<T>;
		root->left = root->right = NULL;
		root->data = x;
		return;
	}
	if (x < root->data)
		insert(root->left, x);
	else
		insert(root->right, x);
}
template <class T>
bool findtnode ( tNode<int>* root, T x)
{
	tNode<T>* cur = root;
	while (cur)
	{
		if (cur->data == x)
		{
			return 1;
		}
		else if (cur->data < x)
		{
			cur = cur->right;
		}
		else
		{
			cur = cur->left;
		}
	}
	return 0;
 }
void firstroot(tNode<int>* root)
{
	if (!root) return;
	cout << root->data << " ";
	firstroot(root->left);
	firstroot(root->right);
}

void inroot(tNode<int>* root)
{
	if (!root) return;
	inroot(root->left);
	cout << root->data << " ";
	inroot(root->right);
}

tNode<int>* root;
int n;
int main()
{
	cin >> n;
	root = NULL;
	for (int i = 1; i <= n; i++)
	{
		int a;
		cin >> a;
		insert(root, a);
	}

	firstroot(root);
	cout << endl;
	inroot(root);
	return 0;
}

/*
9
7 4 2 6 17 11 13 8 9
*/

树变二叉树

//孩子兄弟表示法  树变二叉树
//x第一个孩子是x左孩子  x的兄弟是他的右儿子 
//树的后序是二叉树的中序
//树的前序是二叉树的前序

#include<bits/stdc++.h>
using namespace std;

/*
输入一棵树,构造该树对应的二叉树,并输出二叉树的层序
遍历结果。
【输入格式】
节点数
节点的编号  子结点个数 各子结点编号 
【输出格式】
先根遍历序列 
后根遍历序列 
*/

const int dMax = 5;
template<class T>
struct tNode
{  T  data;
   tNode *p[dMax];
};
const int MAXSIZE = 20000;
tNode<int> tree[MAXSIZE]; 
int  N;

template<class T>	//二叉树节点 
struct bNode
{  T  data;
   bNode *L, *R;
};
bNode<int> *bTree;	//二叉树

template<class T>
void createBTree(tNode<T> *tP, bNode<T> *& bP)
{	if(!tP)	return;

	bP = new bNode<T>;
	bP->data = tP->data;	
	bP->L = bP->R = NULL;
	
	//tP的第一个孩子成为节点bP的左孩子 
	if(!tP->p[0])	return;
	createBTree(tP->p[0], bP->L);
	
	//tP的其余孩子成为节点bP的左孩子的右孩子、
	//左孩子的右孩子的右孩子、... 
	bNode<T> *tmp = bP->L; 
	for(int i=1; i<dMax; i++)
	{	if(!tP->p[i])	return;
		createBTree(tP->p[i], tmp->R);
		tmp = tmp->R;
	}
	
//	bNode<T> *tmp = bP->L->R;//这么是错的,参数传递不正确! 
//	for(int i=1; i<dMax; i++)
//	{	if(!tP->p[i])	return;
//		createBTree(tP->p[i], tmp);
//		tmp = tmp->R;
//	}
}

template<class T>
void levelOrder(bNode<T> *p)
{	

}
template<class T>
void preOrder(bNode<T> *p)
{	if (!p)	return;
	cout<<p->data<<" ";
	preOrder(p->L);
	preOrder(p->R);
}
template<class T>
void postOrder(bNode<T> *p)
{	if (!p)	return;
	postOrder(p->L);
	postOrder(p->R);
	cout<<p->data<<" ";	
}
int main()
{	int  a, c, id;
	
	//构建树 
	cin>>N;
	for(int i=0; i<N; i++)	
	{	cin>>a>>c;
		tree[a].data = a;
		for(int j=0; j<c; j++)
		{	cin>>id;
			tree[a].p[j] = &tree[id];
		}
	}
	
	createBTree(&tree[1], bTree);
	
	cout<<"先序序列:";	
	preOrder(bTree);	cout<<endl;
	cout<<"后序序列:";	
	postOrder(bTree);	cout<<endl;
	return 1;
}

/*
输入样例1:
12
1 3 2 12 3
2 3 4 6 8
3 2 9 11
4 0
5 0
6 2 5 7
7 0
8 0
9 1 10
10 0
11 0 
12 0
输出样例1;
1  2  4  6  5  7   8  12  3   9  10  11
4  5  7  6  8  2  12  10  9  11   3   1
*/

五、图

邻接表

#include<iostream>
using namespace std;
const int maxn=1e3;
int cin_g[maxn][maxn];
int n;

struct node{
	node *next;
	int val;
	int id;
}v[maxn];
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		v[i].next=NULL;
		for(int j=0;j<n;j++)
		{
			cin>>cin_g[i][j];
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(cin_g[i][j]>0)
			{
				node* va=new node;
				va->val=cin_g[i][j];
				va->next=NULL;
				va->id=j;
				if(!v[i].next)v[i].next=va;
				else
				{
					node* p=new node;
					p=v[i].next;
					while(p)
					{
						if(!p->next)
						{
							p->next=va;
							break;
						}
						else	p=p->next;
					}
				}
			}
		}
	}
	for(int i=0;i<n;i++)
	{
		node* pp=v[i].next;
		while(pp)
		{
			cout<<i<<"->"<<pp->id<<"权值是"<<pp->val<<" ";
			pp= pp->next;
		}
		cout<<endl;
	 } 
	return 0;
	
}

/*
3
1 0 1
5 2 0
4 5 6
*/

简洁版邻接表

#include<iostream>
#define next nex
using namespace std;
const int maxn=1000001;
int first[maxn],next[maxn<<1],to[maxn<<1],val[maxn<<1],tot;
int n,m;
void add(int x,int y,int z)
{
	next[++tot]=first[x];
	first[x]=tot;
	to[tot]=y;
	val[tot]=z;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int x,y;
		cin>>x>>y;
		add(x,y,1);
	}
	for(int e=first[2];e;e=next[e])
	{
		cout<<2<<"->"<<to[e]<<endl;
	}
	return 0;
}

/*
6 5
1 2 
2 3 
2 4 
2 5 
1 6
*/


/*
#include<iostream>
using namespace std;
#define next nex
const int maxn=1001;
int first[maxn],next[maxn<<1],to[maxn<<1],val[maxn<<1];
int tot;
void add(int x,int y,int z)
{
	next[++tot]=first[x];
	first[x]=tot;
	to[tot]=y;
	val[tot]=z;
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	for(int i=1;i<=n;i++)
	{
		for(int e=first[i];e;e=next[e])
		{
			int v=to[e];
			int d=val[e];
			cout<<v<<" "<<d<<" "<<endl;
		}
	}
}

*/

连接多重表

#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>

using namespace std;
int n, m;
struct Edge {
	bool vis;
	char i;
	int ilink;
	char j;
	int jlink;
}edge[103];

struct Node {
	char dataa;
	int pos;
}node_firstpos[12];

void insert(char x, char y, int pos)
{
	edge[pos].vis = false;
	edge[pos].i = x;
	edge[pos].j = y;
	edge[pos].ilink = 0;
	edge[pos].jlink = 0;
	for (int i = 1; i <= n; i++)
	{
		if (node_firstpos[i].dataa == x || node_firstpos[i].dataa == y)
		{
			int tmp = node_firstpos[i].pos;
			int tmp_dataa = node_firstpos[i].dataa;
			if (tmp == 0)
			{
				node_firstpos[i].pos = pos;
			}
			else {
				int tm = 0;
				while (tmp != 0)
				{
					tm = tmp;
					if (edge[tmp].i == tmp_dataa)
					{
						tmp = edge[tmp].ilink;
					}
					else {
						tmp = edge[tmp].jlink;
					}
				}
				if (edge[tm].i == tmp_dataa)
				{
					edge[tm].ilink = pos;
				}
				else {
					edge[tm].jlink = pos;
				}
			}
		}
	}
}

void pri()
{
	for (int i = 1; i <= m; i++)
	{
		cout << edge[i].i << " " << edge[i].ilink << " " << edge[i].j << " " << edge[i].jlink << endl;
	}
}
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		char da;
		cin >> da;
		node_firstpos[i].dataa = da;
		node_firstpos[i].pos = 0;
	}
	cin >> m;
	for (int i = 1; i <= m; i++)
	{
		char x, y;
		cin >> x >> y;
		insert(x, y, i);
	}
	pri();
	return 0;
}

/*
5
A B C D E
6
A B
A C
C B
C E
D B
C D
*/

宽度优先遍历

#include<iostream>
#include<queue>
using namespace std;
#define next nex
const int maxn=1e3+1;
int tot,first[maxn],next[maxn<<1],to[maxn<<1],val[maxn<<1];
int vis[maxn];
void graph(int x,int y,int z)
{
	next[++tot]=first[x];
	first[x]=tot;
	to[tot]=y;
	val[tot]=z;
}
queue<int>q;
int m;
int main()
{
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		char x,y;
		cin>>x>>y;
		graph(x-'A',y-'A',1);
	}
	q.push(0);
	vis[0]=1;
	
	while(!q.empty())
	{
		int i=q.front();
		q.pop();
		cout<<char(i+'A')<<" ";
		for(int e=first[i];e;e=next[e])
		{
			if(vis[to[e]]==0)
			{
				q.push(to[e]);
				vis[to[e]]=1;
			}
		}
	}
	return 0;	
	
} 



/*
编程实现无向图的宽度优先遍历。顶点用大写字母表示。
假设从顶点A开始搜索。

#include<bits/stdc++.h>
using namespace std;

const int MAXSIZE = 200;
bool G[MAXSIZE][MAXSIZE], B[MAXSIZE];
int N;	//边的数量 

int main()
{	char x, y;

	cin>>N;
	for(int i=1; i<=N; i++)
	{	cin>>x>>y;
		G[x][y] = G[y][x] = 1;
	}
	
	//广搜
	queue<char>	q;
	q.push('A');	B['A'] = 1;
	while(q.size())
	{	char x = q.front();	
		q.pop();
		cout<<x<<" ";
		for(int i='A'; i<='Z'; i++)
		{	if(!G[x][i])	continue;//边(x,i)不存在 
			if(B[i])	continue;//顶点i已经被访问 
			q.push(i);
			B[i] = 1;
		}
	}
	return 0;
}
*/
/*
【输入样例1】
7
A B
A F
A C
B F
B D
D C
E F
【输出样例1】
A B C F D E
【输入样例2】
9
A B
A C
A E
B D
B E
C E
D E
E F
F C
【输出样例2】
A B C E D F
*/

深度优先遍历

#include<iostream>
#include<queue>
using namespace std;
#define next nex
const int maxn=1e3+1;
int tot,first[maxn],next[maxn<<1],to[maxn<<1],val[maxn<<1];
int vis[maxn];
void graph(int x,int y,int z)
{
	next[++tot]=first[x];
	first[x]=tot;
	to[tot]=y;
	val[tot]=z;
}
void dfs(int x)
{
	cout<<char(x+'A')<<"   ";
	vis[x]=1;
	for(int e=first[x];e;e=next[e])
	{
		int u=to[e];
		if(!vis[u])
		{
			dfs(u);
		}
	}
} 
int m;
int main()
{
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		char x,y;
		cin>>x>>y;
		graph(x-'A',y-'A',1);
	}
	dfs(0);
	return 0;
}



/*
编程实现有向图的深度优先遍历。顶点用大写字母表示。

#include<bits/stdc++.h>
using namespace std;
const int MAXSIZE = 200;
bool G[MAXSIZE][MAXSIZE], B[MAXSIZE];
int N;	//边的数量 

void dfs(char x)
{	cout<<x<<" ";
	B[x] = 1;
	for(int i='A'; i<='Z'; i++)
	{	if(!G[x][i])	continue;//边(x,i)不存在 
		if(B[i])	continue;//顶点i已经被访问 
		dfs(i);
		//B[i] = 1;
	}
}
 
int main()
{	char x, y;

	cin>>N;
	for(int i=1; i<=N; i++)
	{	cin>>x>>y;
		G[x][y] = 1;
	}
	
	//深搜
	dfs('A');
	return 0;
}

/*
【输入样例1】
9
A B
A C
A E
B D
B E
C E
D E
E F
F C
【输出样例1】
A B D E F C
【输入样例2】
7
A B
A F
A C
B F
B D
D C
E F
【输出样例2】
A B D C F    //注意:E搜不到  要想搜到E,还需要增加检查代码 
*/

最小生成树克鲁斯卡尔

#include<bits/stdc++.h>
using namespace std;
const int maxn=200005;
const int point=5003;
int ans,n,m;
int f[maxn];
struct node{
	int x;
	int y;
	int val;
}g[maxn];
int find(int x)
{
	if(f[x]==x)
	{
		return x;
	}
	else return f[x]=find(f[x]);
}
int cmp(node &a,node &b)
{
	return a.val <b.val ;
}
void kruskal()
{
	int k=0;
	for(int i=1;i<=m;i++)
	{
		int v=g[i].x ;
		int u=g[i].y ;
		int a=find(v);
		int b=find(u);
		if(a!=b)
		{
			f[a]=b;
			ans+=g[i].val ;
			k++;
		}
		if(k==n-1)
		break;
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>g[i].x>>g[i].y>>g[i].val;
	}
	for(int i=1;i<=n;i++)
	{
		f[i]=i;
	}
	sort(g+1,g+m+1,cmp);
	kruskal();
	cout<<ans<<endl;
	return 0;
}

最小生成树prim

//将所有点分为两个集合 一个集合为最小生成树里面的,另一个是没有选中的。
//选一个点放树里,看他到另一个集合的最短的边,将那个点更新到树里 

#include<iostream>
#include<cstring> 
using namespace std;
#define next nex
const int maxn=200005;
const int point=5003;
int first[point],next[maxn<<1],to[maxn<<1],val[maxn<<1],tot;
int n,m,res;
void add(int x,int y,int z)
{
	next[++tot]=first[x];
	first[x]=tot;
	to[tot]=y;
	val[tot]=z;
}
struct node{
	int pre;
	int weight;
}dis[maxn];
int vis[maxn];
void prim()
{
	dis[1].weight=0;
	dis[1].pre=1;
	for(int i=1;i<=n;i++)
	{
		int ans=1e9;
		int k;
		for(int j=1;j<=n;j++)
		{
			if(vis[j]==0&&dis[j].weight<ans)
			ans=dis[j].weight,k=j;
		}
		vis[k]=1;
		if (k!=1)cout<<dis[k].pre<<"   "<<k<<" "<<endl;
		for(int e=first[k];e;e=next[e])
		{
			int u=to[e];
			if(vis[u]==0&&dis[u].weight>val[e])
			{
				dis[u].weight=val[e];
				dis[u].pre=k;
			}
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	memset(dis,0x7f,sizeof(dis));
	prim();
	cout<<endl;
	for(int i=1;i<=n;i++)
	{
		if(vis[i]==0)
		{
			cout<<"orz"<<endl;return 0;
		}
		else
		res+=dis[i].weight;
	}
		cout<<res<<endl;
	return 0;
}


/* Prim算法 
输入一个带权图,构造其最小生成树。依次输出每一次选中的边。
【输入格式】
n(顶点数)
e(边数)
以下e行,每行3个数i,j,wij,表示在顶点i,j之间的权值
*/

/*
#include<bits/stdc++.h>
using namespace std;

int g[101][101];// 邻接矩阵
int minn[101];  // minn[i]存放蓝点i与白点相连的最小边权
int pre[101];   // pre[i]记录点i的minn[i]对应的连接点 
bool b[101];    // b[i]=false,表示i是蓝点 
int n, e;
int main()
{   int x, y, w, k;
    
    memset(minn, 0x7f, sizeof(minn)); //初始化为maxint
    minn[1] = 0;    pre[1] = 0;//首先选择顶点1 
    cin>>n>>e;
    for(int i=1; i<=e; i++)
    {   cin>>x>>y>>w;
        g[x][y]=g[y][x]=w;
    }
    
    for(int i=1; i<=n; i++)//一共n个顶点,顶点1肯定首先选中 
    {   k = 0;
        for(int j=1; j<=n; j++) //找minn[]最小的蓝点k
            if(!b[j] && (minn[j]<minn[k]))
                k = j;
        b[k] = 1;           // 标记k为白点
        if(k!=1)    cout<<pre[k]<<" "<<k<<endl;
        for(int j=1; j<=n; j++) //修改与k相连的所有蓝点
            if(!b[j] && g[k][j] && g[k][j]<minn[j])
            {   minn[j] = g[k][j]; 
                pre[j] = k;
            }
    }   
    return 0;
}
/*
【输入样例1】
5 8
1 2 2
2 5 9
5 4 7
4 1 10
1 3 12
4 3 6
5 3 3
2 3 8
【输出样例1】
1 2
2 3
3 5
3 4
【输入样例2】 //对应PPT上的图 A~F用1~6表示 
6 7
1 2 10
1 3 9
1 6 7
2 4 6
2 6 8
3 4 13
5 6 3 
【输出样例2】
1 6
6 5
6 2
2 4
1 3
*/

单源最短路迪杰斯特拉

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
# define next nex
const int maxn=1000001;
int first[maxn],next[maxn<<1],to[maxn<<1],val[maxn<<1],tot;
int n,m;
void add(int x,int y,int z)
{
	next[++tot]=first[x];
	first[x]=tot;
	to[tot]=y;
	val[tot]=z;
}
struct node
{
		int p;int d;//p点 d权值 
		bool operator <(const node &a) const 
		{
			return d>a.d;
		}
};
int dis[maxn],vis[maxn];
int pre[maxn]; 
priority_queue<node>q;
void dijkstra(int s,int t)
{
	dis[s]=0;
	pre[s]=-1;
	q.push((node){s,0}) ;
	while (!q.empty())
	{
		node n1=q.top() ;
		int k=n1.p ;
		q.pop() ;
		if(vis[k]) continue;
		vis[k]=1;
		for(int e=first[k];e;e=next[e])
		{
			int v=to[e];
			if(!vis[v]&&dis[v]>dis[k]+val[e])
			{
				dis[v]=dis[k]+val[e];
				q.push((node){v,dis[v]}) ;
				pre[v]=k;//到v最短的路径 是由k更新来的 
			}
		}
	}
		
}

void prt(int t)//输出路径 
{
	if(pre[t]==-1) 
	{
		cout<<t;
		return ;
	}
	prt(pre[t]);
	cout<<"->"<<t;
}
int main()
{
	cin>>n>>m;
	int s,t;
	cin>>s>>t;
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		add(x,y,z);
		//add(y,x,z);
	}
	memset(dis,0x7f,sizeof(dis));
	dijkstra(s,t);
	cout<<dis[t]<<endl;
	prt(t);
	return 0;
}

/*
5 7
0 3
0 1 13
0 2 38
1 2 15
1 4 14
4 2 6
2 3 19
4 3 17
*/

拓扑排序

#include<iostream>
#include<stack>
#include<vector>
# define next nex
using namespace std;
const int maxn=1e5+3;
vector<int>ans;
int first[maxn],next[maxn<<1],to[maxn<<1]; 
int tot;
void add(int x,int y)
{
	next[++tot]=first[x];
	first[x]=tot;
	to[tot]=y; 
}

int in_num[maxn];
stack<int>sk;

void tuopu(int x)
{
	sk.push(x);
	while(!sk.empty())
	{
		int k=sk.top();
		ans.push_back(k);
		sk.pop();
		for(int e=first[k];e;e=next[e])
		{
			int v=to[e];
			in_num[v]--;
			if(in_num[v]==0)
			{
				sk.push(v);
			}
		}
	}
}
int n,m;

int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		char X ,Y;
		int x,y;
		cin>>X>>Y;
		x=X-'A';
		y=Y-'A'; 
		in_num[y]++;
		add(x,y);
	}
	for(int i=0;i<n;i++)
	{
		if(in_num[i]==0)
		{
			tuopu(i);
		}
	}
	for(int i=0;i<n;i++)
	{
		cout<<char(ans[i]+'A')<<"  ";
	}
	return 0;
}
/*
5 5
A B
A C
B E
C D
E D


ABCED
ABECD
*/

  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值