import'dart:io';/// DataItem class represented a data in TreeclassDataItem{intdata;DataItem(this.data){}voiddisplayItem(){stdout.write('/$data');}}classNode{staticfinalintORDER=4;intnumItems=0;Nodeparent;List<Node>childArray=newList<Node>(ORDER);List<DataItem>itemArray=newList<DataItem>(ORDER-1);/// Connect Child to ParentvoidconnectChild(intchildNum,Nodechild){childArray[childNum]=child;if(child!=null){child.parent=this;}}/// Disconnect Child from Node and return itNodedisconnectChild(intchildNum){Nodetemp=childArray[childNum];childArray[childNum]=null;returntemp;}NodegetChild(intchildNum){returnchildArray[childNum];}NodegetParent(){returnparent;}boolisLeaf(){return(childArray[0]==null);}intgetNumItems(){returnnumItems;}/// Get DataItem by indexDataItemgetItem(intindex){returnitemArray[index];}boolisFull(){return(numItems==ORDER-1);}/// Find Element index in NODE or return -1intfindItem(intkey){for(inti=0;i<ORDER-1;i++){if(itemArray[i]==null){break;}elseif(itemArray[i].data==key){returni;}}return-1;}/// Insert new Item to Node////// Return new element indexintinsertItem(DataItemnewItem){numItems++;intnewKey=newItem.data;for(inti=ORDER-2;i>=0;i--){if(itemArray[i]==null){continue;}else{intitsKey=itemArray[i].data;if(newKey<itsKey){itemArray[i+1]=itemArray[i];}else{itemArray[i+1]=newItem;returni+1;}}}itemArray[0]=newItem;return0;}/// Delete max itemDataItemremoveItem(){DataItemtemp=itemArray[numItems-1];itemArray[numItems-1]=null;numItems--;returntemp;}voiddisplayNode(){for(inti=0;i<numItems;i++){itemArray[i].displayItem();}stdout.writeln();}}classTree234{Noderoot=newNode();intfind(intkey){NodecurNode=root;intchildNumber=curNode.findItem(key);while(true){if(childNumber!=-1){returnchildNumber;}elseif(curNode.isLeaf()){return-1;}else{curNode=getNextChild(curNode,key);}}}/// Insert data elementvoidinsert(intdata){NodecurNode=root;DataItemtemItem=newDataItem(data);while(true){if(curNode.isFull()){split(curNode);curNode=curNode.getParent();curNode=getNextChild(curNode,data);}elseif(curNode.isLeaf()){break;}else{curNode=getNextChild(curNode,data);}}curNode.insertItem(temItem);}/// Split Nodevoidsplit(NodethisNode){DataItemitemB,itemC;Nodeparent,child2,child3;intitemIndex;itemC=thisNode.removeItem();itemB=thisNode.removeItem();child2=thisNode.disconnectChild(2);child3=thisNode.disconnectChild(3);NodenewRight=newNode();/// If Node is Root -> create a new Rootif(thisNode==root){root=newNode();parent=root;root.connectChild(0,thisNode);}else{parent=thisNode.getParent();}itemIndex=parent.insertItem(itemB);intn=parent.getNumItems();for(inti=n-1;i>itemIndex;i--){Nodetemp=parent.disconnectChild(i);parent.connectChild(i+1,temp);}parent.connectChild(itemIndex+1,newRight);newRight.insertItem(itemC);newRight.connectChild(0,child2);newRight.connectChild(1,child3);}NodegetNextChild(Nodenode,intvalue){inti;intnumItems=node.getNumItems();for(i=0;i<numItems;i++){if(value<node.getItem(i).data){returnnode.getChild(i);}}returnnode.getChild(i);}voiddisplayTree(){recursionDisplayTree(root,0,0);}voidrecursionDisplayTree(Nodenode,intlevel,intchildNumber){stdout.write('Level = $level child = $childNumber ');node.displayNode();intnumItems=node.getNumItems();for(inti=0;i<numItems+1;i++){NodenextNode=node.getChild(i);if(nextNode!=null){recursionDisplayTree(nextNode,level+1,i);}else{return;}}}}voidmain(List<String>args){intvalue;Tree234tree234=newTree234();tree234.insert(50);tree234.insert(40);tree234.insert(60);tree234.insert(30);tree234.insert(70);while(true){stdout.write('Enter first letter of show, insert, find: ');Stringchoice=stdin.readLineSync();switch(choice){case's':tree234.displayTree();break;case'i':stdout.write('Enter value to insert: ');value=int.parse(stdin.readLineSync());tree234.insert(value);break;case'f':stdout.write('Enter value to find: ');value=int.parse(stdin.readLineSync());intfound=tree234.find(value);if(found!=-1){stdout.writeln('Found $value');}else{stdout.writeln('Could now find $value');}break;default:stdout.writeln('Invalud entry');}}}