データ構造アルゴリズム設計問題の専門化


信頼できる情報によると、アルゴリズム設計の質問は主に以下に焦点を当てています。

第2章、第3章、第7章、第8章



それぞれ

  • 第2章線形テーブル

  • 第3章スタックとキュー

  • 第7章検索

  • 第8章並べ替え


メイン

挿入の前後に挿入して単一リンクリストを作成し、順序付きリンクリストにマージします

線形テーブル放課後演習アルゴリズム設計の問題1、7

チェーンスタックのプッシュアンドポップ

チェーンチーム

半分で見つける

バブルソート

クイックソート

ヒープソート


挿入の前後に挿入して単一リンクリストを作成し、順序付きリンクリストにマージします

コードの説明:

void CreateList_H(LinkList& L, int n)
{
	L = new Lnode;
	L->next = NULL;
	for (int i = 0; i < n; ++i) {
		p = new Lnode;
		cin >> p->data;
		p->next = L->next;
		L->next = p;
	}
}


アルゴリズムの時間の複雑さはO(n)です。

void CreateList_R(LinkList& L, int n) {
	L = new Lnode;
	L->next = NULL;
	r = L;
	for (i = 0; i < n; ++i) {
		p = new Lnode;
		cin >> p->data;
		p->next = null;
		r->next = p;
		r = p;
	}
}

アルゴリズムの時間の複雑さはO(n)です。


void MergeList(LinkList& La, LinkList& Lb, LinkList& Lc)
{
    
    
	pa = La->next;  pb = Lb->next;
	
	Lc = pc = La;  //用La的头结点作为Lc的头结点
	while (pa && pb)
	{
    
    
		if (pa->data < pb->data) {
    
     pc->next = pa; pc = pa; pa = pa->next; }
		//取较小者La中的元素,将pa链接在pc的后面,pa指针后移
		else if (pa->data > pb->data) {
    
     pc->next = pb; pc = pb; pb = pb->next; }
		//取较小者Lb中的元素,将pb链接在pc的后面,pb指针后移
		else //相等时取La中的元素,删除Lb中的元素
		{
    
    
			pc->next = pa; pc = pa; pa = pa->next;
			q = pb->next; delete pb; pb = q;
		}
	}
	pc->next = pa ? pa : pb;    //插入剩余段
	delete Lb;            //释放Lb的头结点
}

線形テーブル放課後演習アルゴリズム設計の問題1、7

2. P53アルゴリズム設計の問題(1)(7)

(1)2つの昇順リンクリストを1つの昇順リンクリストに結合します。結果のリンクリストは、元の2つのリンクリストのストレージスペースを引き続き使用し、他のストレージスペースを占有しないようにする必要があります。テーブル内での重複データは許可されていません。

上記と同じ!


(7)リンクリスト内のすべてのノードのリンク方向を「insitu」で反転するアルゴリズムを設計します。つまり、元のテーブルのストレージスペースのみが必要です。つまり、アルゴリズムのスペースの複雑さは0です(1)。

//利用的是前插法
void Do(LinkList& L) {
    
    

	//1->2->3->4
	r = L->next;
	L->next = NULL;
	while (r) {
    
    
		p = r->next;
		r->next = L->next;
		L->next = r;
		r = p;
	}
}

チェーンスタックのプッシュアンドポップ

void Push(LinkStack& L, SElemType e) {
    
    
	p = new StackNode;
	p->data = e;
	p->next = L;
	L = p;
}
void pop(LinkStack& L, SElemType e) {
    
    
	if (L == NULL)e = NULL;
	else
	{
    
    
		p = L;
		e = L->data;
		L = L->next;
		delete p;
	}
}

半分で見つける

int search_bin(SStable ST,keyType key){
    
    
low =1;
hight = ST.length;
while(low<=high
{
    
    
	mid = (low + high)/2;
	if(key == ST.R[mid].key)
		return mid;
	else if (key<ST.R[mid].key)
		high = mid-1
	else low = mid +1

}
return 0;


バブルソート

void BubbleSort(Sqlist &L)
{
    
    
	m = L.length - 1 ;
	flag = 1;
	while ((m>0)&&(flag==1))
	{
    
    
		flage = 0;
		for (j=1;j<=m;j++){
    
    
			if(L.r[j].key>L.r[j+1].key)
			{
    
    
				flag = 1;
				t = L.r[j];
				L.r[j]=L.r[j+1];
				L.r[j+1] = t;
			}
			--m;
		}
	
	}
}



キューがヘッドノードとの循環リンクリストで表され、キューの終了要素ノードを指すポインターが1つだけ設定されていると仮定して(注:ヘッドポインターは設定されていません)、対応する空のキューを書き込んで、キューが空かどうかを判断し、入力してデキューしますそして他のアルゴリズム

ここに写真の説明を挿入ここに写真の説明を挿入
ここに写真の説明を挿入


数学には有名な「アッカーマン(アッカーマン)関数」があり、次のように定義されています。

ここに写真の説明を挿入
(1)Ack(m、n)の再帰的アルゴリズムを書く

int Ack(int m, int n)
//Ack函数的递归算法
{
    
    
If(m==0)
   return n+1;
else if (m!=0 && n==0)
   return Ack(m-1, 1);
Else
   return Ack(m-1,Ack(m,m-1));
}

(2)Ack(m、n)を計算するための非再帰的アルゴリズムを記述します。

int Ack(int m, int n)
//Ack函数的递归算法
{
    
    
    for(j=0;j<n;j++) 
    akm[0][j] = j+1;//得到Ack(0,n)的值
    for(i=0;i<m;i++)
    {
    
    
        akm[i][0] = akm[i-1][1];
        for(j=1;j<n;j++)
        akm[i][j] = akm[i-1][akm[i][j-1]];
    }
    return akm[m][n];
}

おすすめ

転載: blog.csdn.net/Touale/article/details/112971662