前回
今回
前回は、Hello_Variable構造体に初期化関数vを追加して、初期化関数vを実行した後にHello構造体の関数uを実行しました。それに伴って、Hello_Variable構造体、executeListFunction関数、main関数を修正し、f_u関数、f_v関数を追加しました。
今回は、POSIXのpthreadを用いて、thread処理をexecuteListFunction関数に追加しました。このthread処理によって各リストにある関数ポインタは、並列に処理されます。並列化できますので計算機資源は効率よく使われますので、結果的に処理速度は早くなる傾向があります。
今回の処理では、thread1関数をソースコードに追加しました。並列処理では、この関数が並列実行されます。
参考ページ
IBM Documentation Help【pthread_create() - スレッドの作成】
だえうホームページ【入門者向け!C言語でのマルチスレッドをわかりやすく解説】
モノづくりC言語塾 C言語 関数ポインタ【ポインタを使って関数を呼ぶ仕組み解説】
SAMEBASE サメベース 【[C言語]双方向リストとその基本操作(追加、削除、挿入)関数の実装[コード付]】
Programming Place Plus 【連結リスト②(双方向・循環) | Programming Place Plus アルゴリズムとデータ構造編【データ構造】 第4章】
参考文献
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
大槻兼資・著 秋葉拓哉・監修
準備
今回はオンラインコンパイラを使用します。
オンラインコンパイラ
Cコンパイラの環境を選んでください。
ソースコード
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
//Hello_Variable型を定義する
typedef struct Hello_Variable {
long i;
double d[11];
struct Hello_Variable* (*v)(struct Hello_Variable*);
}Hello_Variable;
//関数fを代入することを想定して、関数ポインタfupo型を定義する
typedef Hello_Variable* (*fupo_v)(Hello_Variable*);
//関数fを代入することを想定して、fupo型の変数uを構造体Hello型の内に定義する
typedef struct Hello {
long searchKey;
Hello_Variable j;
struct Hello* (*u)(struct Hello*);//引数に関数ポインタを持つ関数ポインタu
}Hello;
//関数fを代入することを想定して、関数ポインタfupo型を定義する
typedef Hello* (*fupo_u)(Hello* v);
// ノードの構造体
typedef struct Node {
long type;
void *data;
struct Node* next;
struct Node* prev;
}Node;
// 新しいノードを作成する関数
struct Node* createNode(void *data,long type) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("メモリの割り当てに失敗しました\n");
exit(1);
}
newNode->type = type;
newNode->data = data;
newNode->next = NULL;
newNode->prev = NULL;
return newNode;
}
// リストの先頭にノードを挿入する関数
void insertAtBeginning(struct Node** head, void *data, long type) {
struct Node* newNode = createNode(data,type);
newNode->next = *head;
if (*head != NULL) {
(*head)->prev = newNode;
}
*head = newNode;
}
// リストの末尾にノードを挿入する関数
void insertAtEnd(struct Node** head, void *data, long type) {
struct Node* newNode = createNode(data,type);
struct Node* current = *head;
if (current == NULL) {
*head = newNode;
} else {
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
newNode->prev = current;
}
}
// リストから指定したノードを削除する関数
void deleteNode(struct Node** head, struct Node* target) {
if (*head == NULL || target == NULL) {
return; // リストが空または対象ノードが存在しない場合は何もしない
}
// 対象ノードの前後のノードを連結
if (target->prev != NULL) {
target->prev->next = target->next;
} else {
*head = target->next; // 対象ノードが先頭の場合
}
if (target->next != NULL) {
target->next->prev = target->prev;
}
free(target); // ノードを解放
}
// リスト内で特定の要素を探す関数
struct Node* search(struct Node* head, long key) {
struct Node* current = head;
while (current != NULL) {
if(current->type==0){
if (((Hello*)current->data)->searchKey == key) {
return current;//ノードが見つかった場合、そのノードを返す
}
}
current = current->next;
}
return NULL; // ノードが見つからなかった場合、NULLを返す
}
// リストを表示する関数
void printList(struct Node* head) {
struct Node* current = head;
while (current != NULL) {
if(current->type==0){
//Hello型関数ポインタuを実行
printf("%ld, ", ((Hello*)current->data)->searchKey);
//Hello_Variable型変数j.iを表示
printf("%ld -> ", ((Hello*)current->data)->j.i);
}
current = current->next;
}
printf("NULL\n");
}
void *thread1(void *arg)
{
Hello* data = (Hello*)arg;
//Hello型関数ポインタj.vを実行
data->j.v(&data->j);
//Hello型関数ポインタuを実行
data->u(data);
//Hello_Variable型変数j.iを表示
printf(",%ld -> ", data->j.i);
pthread_exit((void*)data);
return (void*)data;
}
// リストを表示する関数
void executeListFunction(struct Node* head) {
int rc;
pthread_attr_t attr;
struct Node* thread_list=NULL;
struct Node* current = head;
long limit=10000000;
pthread_t thid[limit];
long count=0;
rc = pthread_attr_init(&attr);
if (rc == -1) {
perror("error in pthread_attr_init");
exit(1);
}
while (current != NULL) {
if(current->type==0){
rc = pthread_create(&thid[count], &attr, thread1, current->data);
if (rc == -1) {
perror("error in pthread_create");
exit(2);
}
if(current->next!=NULL){
insertAtBeginning(&thread_list,&thid[count],-1);
}
else{
insertAtEnd(&thread_list,&thid[count],-1);
}
count++;
if(count>=limit){
break;
}
}
current = current->next;
}
Node* th_current=thread_list;
while (th_current!=NULL) {
if(th_current->type==-1){
void *s=NULL;
if (pthread_join(*(pthread_t*)th_current->data, &s) != 0) {
perror("pthread_create() error\n");
exit(3);
}
printf("%ld \n",(*(Hello*)s).searchKey);
}
th_current = th_current->next;
}
printf("NULL\n");
}
Hello_Variable* f_v(Hello_Variable* q){
//引数v->dに値を代入
q->d[q->i]=0;
//引数v->dを表示
printf("_%1.2lf_",q->d[q->i]);
//引数v->iに1を加算
q->i++;
if(q->i<=10){
//引数iが10以下のとき引数関数v->uを再帰呼び出し
q=q->v(q);
}
else{
//変数q->iを初期化
q->i=0;
//改行
printf("\n");
//引数iが10より上になったらHELLO_VARIABLEポインタ型vを返す
return q;
}
return q;
}
Hello* f_u(Hello* v){
//引数v->dに値を代入
v->j.d[v->j.i]=1+(v->j.i*0.1);
//引数v->dを表示
printf("_%1.2lf_",v->j.d[v->j.i]);
//引数v->iに1を加算
v->j.i++;
if(v->j.i<=10){
//引数iが10以下のとき引数関数v->uを再帰呼び出し
v=v->u(v);
}
else{
printf("\n");
//引数iが10より上になったらHELLO_VARIABLEポインタ型vを返す
return v;
}
return v;
}
int main() {
struct Node* myList = NULL;
int ri=61;
Hello data[ri];
fupo_v q=f_v;
fupo_u r=f_u;
int i=0;
for(;i<ri;i++){
//Hello_Variable型変数j.iに0を代入
data[i].j.i=0;
//searchKeyに検索キー番号を代入
data[i].searchKey=i;
//関数f_uを代入
data[i].u=r;
//関数f_vを代入
data[i].j.v=q;
}
for(i=0;i<ri-1;++i){
// リストに要素を追加
insertAtBeginning(&myList, &data[i],0);
}
insertAtEnd(&myList, &data[i],0);
// リストの関数を実行
executeListFunction(myList);
// リストを表示
printf("双方向リスト: ");
printList(myList);
long searchKey = 2;
struct Node* foundNode = search(myList, searchKey);
if (foundNode != NULL) {
printf("%ld が見つかりました\n", searchKey);
} else {
printf("%ld は見つかりませんでした\n", searchKey);
}
if (foundNode != NULL) {
// ノードを削除
deleteNode(&myList, foundNode);
// リストを再度表示
printf("削除後の双方向リスト: ");
printList(myList);
}
return 0;
}
実行結果
_0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.00__1.10__1.20__1.30__1.10__1.40__1.50__1.60__1.20__1.70__1.30__1.80__1.40__1.50__1.90__1.60__2.00__1.70__1.80__1.90_
_2.00_,11 ->
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__0.00__1.10__1.20__0.00__1.30__1.40__1.50__0.00__1.60__1.70__1.80__0.00__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__0.00__1.00_
_1.10__1.20__1.00__1.30__1.10__1.40__1.20__1.50__1.30__1.60__1.40__1.70__1.50__1.80__1.60__1.90__1.70__2.00__1.80_
_1.90__2.00_,11 ->
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00__0.00__1.10_
_1.20__1.30__1.00__1.40__1.10__1.50__1.20__1.60__1.30__1.70__1.40__1.80__1.50__1.90__1.60__2.00__1.70_
_1.80_,11 -> _1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00_
_1.10__1.00__1.20__1.10__1.30__1.20__1.40__1.30__1.50__1.40__1.60__1.50__1.70__1.60__1.80__1.70__1.90__1.80__2.00__1.90_
_2.00_,11 ->
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00_
_1.10__1.00__1.20__1.10__1.30__1.20__1.40__1.30__1.50__1.40__1.60__1.50__1.70__1.60__1.80__1.70__1.90__1.80__2.00__1.90_
_2.00_,11 ->
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.00__1.10__1.10__1.20__1.20__1.30__1.30__1.40__1.40__1.50__1.50__1.60__1.60__1.70__1.70__1.80__1.80__1.90__1.90__2.00__2.00_
,11 -> ,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.00__1.10__1.10__1.20__1.20__1.30__1.30__1.40__1.40__1.50__1.50__1.60__1.60__1.70__1.70__1.80__1.80__1.90__1.90__2.00__2.00_
,11 -> ,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.00__1.10__1.10__1.20__1.20__1.30__1.30__1.40__1.40__1.50__1.50__1.60__1.60__1.70__1.70__1.80__1.80__1.90__1.90__2.00__2.00_
,11 -> ,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.00__1.10__1.10__1.20__1.20__1.30__1.30__1.40__1.40__1.50__1.50__1.60__1.60__1.70__1.70__1.80__1.80__1.90__1.90__2.00__2.00_
,11 -> ,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.00__1.10__1.10__1.20__1.20__1.30__1.30__1.40__1.40__1.50__1.50__1.60__1.60__1.70__1.70__1.80__1.80__1.90__1.90__2.00__2.00_
,11 -> ,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00_
_1.10__1.00__1.20__1.10__1.30__1.20__1.40__1.30__1.50__1.40__1.60__1.50__1.70__1.60__1.80__1.70__1.90__1.80__2.00__1.90_
_2.00_,11 ->
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00_
_1.10__1.00__1.20__1.10__1.30__1.20__1.40__1.30__1.50__1.40__1.60__1.50__1.70__1.60__1.80__1.70__1.90__1.80__2.00__1.90_
_2.00_,11 ->
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__0.00__1.10__1.20__1.30__0.00__1.40__1.50__1.60__0.00__1.70__1.80__1.90__0.00__2.00__0.00_
_0.00_,11 -> _0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00_
_1.00__1.00__1.10__1.10__1.20__1.20__1.30__1.30__1.40__1.40__1.50__1.50__1.60__1.60__1.70__1.70__1.80__1.80__1.90__1.90__2.00__2.00_
,11 -> ,11 -> _0.00_
_1.00__0.00__1.10__0.00__1.20__0.00__1.30__0.00__1.40__0.00__1.50__0.00__1.60__0.00__1.70__0.00__1.80__0.00__1.90__0.00__2.00_
,11 -> _1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00_
_1.10__1.00__1.20__1.10__1.30__1.20__1.40__1.30__1.50__1.40__1.60__1.50__1.70__1.60__1.80__1.70__1.90__1.80__2.00__1.90_
_2.00_,11 ->
,11 -> _1.10__1.20__1.30__0.00__1.40__1.50__1.60__1.70__1.80__0.00__0.00__1.40__0.00__1.50__0.00__0.00__0.00__1.60__0.00__1.70__0.00__1.80__0.00__1.90__0.00__2.00__0.00_
_0.00_,11 -> _0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00_
_1.10__1.20__1.00__1.30__1.10__1.40__1.20__1.50__1.30__1.60__1.40__1.70__1.50__1.80__1.60__1.90__1.70__2.00__1.80_
_1.90_,11 -> _2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__0.00__1.00_
_1.10__1.00__1.20__1.10__1.30__1.20__1.40__1.30__1.50__1.40__1.60__1.50__1.70__1.60__1.80__1.70__1.90__1.80__2.00__1.90_
_2.00_,11 ->
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00__0.00__1.10__0.00__1.20__0.00__1.30__0.00__1.40__0.00__1.50_
_1.60__1.70__1.00__1.80__1.10__1.90__1.20__2.00__1.30_
_1.40_,11 -> _1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__2.00__0.00__0.00_
_1.00_
_1.10__1.20_,11 -> _1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00__0.00__1.10__0.00__1.20__0.00__1.30_
_1.40__1.50__1.00__1.60__1.10__1.70__1.20__1.30__1.80__1.40__1.90__1.50__2.00__1.60_
_1.70_,11 -> _1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_0.00__1.00__0.00__1.10__0.00__1.20__0.00__1.30__0.00__1.40_
_1.50__1.60__1.00__1.70__1.10__1.80__1.20__1.90__1.30__2.00__1.40_
_1.50_,11 -> _1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> _0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_0
1
2
3
4
_0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_5
6
7
8
_0.00_9
_0.00_10
_0.00_11
_1.00__1.10_12
_1.20__1.30_13
_1.40__1.50_14
_1.60__1.70_15
_1.80_16
17
_1.90_18
_2.00_
,11 -> 19
_0.00_
_1.00__1.10_20
_1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> 21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
_0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00__0.00_
_1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
,11 -> 60
NULL
双方向リスト: 59, 11 -> 58, 11 -> 57, 11 -> 56, 11 -> 55, 11 -> 54, 11 -> 53, 11 -> 52, 11 -> 51, 11 -> 50, 11 -> 49, 11 -> 48, 11 -> 47, 11 -> 46, 11 -> 45, 11 -> 44, 11 -> 43, 11 -> 42, 11 -> 41, 11 -> 40, 11 -> 39, 11 -> 38, 11 -> 37, 11 -> 36, 11 -> 35, 11 -> 34, 11 -> 33, 11 -> 32, 11 -> 31, 11 -> 30, 11 -> 29, 11 -> 28, 11 -> 27, 11 -> 26, 11 -> 25, 11 -> 24, 11 -> 23, 11 -> 22, 11 -> 21, 11 -> 20, 11 -> 19, 11 -> 18, 11 -> 17, 11 -> 16, 11 -> 15, 11 -> 14, 11 -> 13, 11 -> 12, 11 -> 11, 11 -> 10, 11 -> 9, 11 -> 8, 11 -> 7, 11 -> 6, 11 -> 5, 11 -> 4, 11 -> 3, 11 -> 2, 11 -> 1, 11 -> 0, 11 -> 60, 11 -> NULL
2 が見つかりました
削除後の双方向リスト: 59, 11 -> 58, 11 -> 57, 11 -> 56, 11 -> 55, 11 -> 54, 11 -> 53, 11 -> 52, 11 -> 51, 11 -> 50, 11 -> 49, 11 -> 48, 11 -> 47, 11 -> 46, 11 -> 45, 11 -> 44, 11 -> 43, 11 -> 42, 11 -> 41, 11 -> 40, 11 -> 39, 11 -> 38, 11 -> 37, 11 -> 36, 11 -> 35, 11 -> 34, 11 -> 33, 11 -> 32, 11 -> 31, 11 -> 30, 11 -> 29, 11 -> 28, 11 -> 27, 11 -> 26, 11 -> 25, 11 -> 24, 11 -> 23, 11 -> 22, 11 -> 21, 11 -> 20, 11 -> 19, 11 -> 18, 11 -> 17, 11 -> 16, 11 -> 15, 11 -> 14, 11 -> 13, 11 -> 12, 11 -> 11, 11 -> 10, 11 -> 9, 11 -> 8, 11 -> 7, 11 -> 6, 11 -> 5, 11 -> 4, 11 -> 3, 11 -> 1, 11 -> 0, 11 -> 60, 11 -> NULL