#include <stdio.h>
#include <stdlib.h>
typedefstruct{intid;inteng;intmath;}student;typedefstudentelement;typedefstructListNode{elementdata;//또는 student data;structListNode*link;}ListNode;ListNode*create_node(intid,inteng,intmath);voidinsert_node(ListNode**phead,ListNode*p,ListNode*new_node);voidascending_insert_node(ListNode**phead,ListNode*new_node);voiddisplay(ListNode*phead);voidinit_node_list(ListNode**p);voidfree_all_node(ListNode**p,intlen);intmain(){constintlen=9;ListNode*p[len];ListNode*head=NULL;inti;init_node_list(p);//node initfor(i=0;i<len;i++)//ascending insertascending_insert_node(&head,p[i]);display(head);//displayfree_all_node(p,len);//freereturn0;}voidinit_node_list(ListNode**p){p[0]=create_node(135,78,55);p[1]=create_node(124,65,70);p[2]=create_node(147,80,85);p[3]=create_node(115,95,90);p[4]=create_node(144,90,80);p[5]=create_node(10,90,80);p[6]=create_node(4000,90,80);p[7]=create_node(343,90,80);p[8]=create_node(343,90,80);}voidfree_all_node(ListNode**p,intlen){inti;for(i=0;i<len;i++){//freefree(p[i]);}}ListNode*create_node(intid,inteng,intmath){ListNode*new_node;new_node=(ListNode*)malloc(sizeof(ListNode));new_node->data.eng=eng;new_node->data.math=math;new_node->data.id=id;return(new_node);}voidinsert_node(ListNode**phead,ListNode*p,ListNode*new_node){if(*phead==NULL){new_node->link=NULL;*phead=new_node;}elseif(p==NULL){new_node->link=*phead;*phead=new_node;}else{new_node->link=p->link;p->link=new_node;}}voidascending_insert_node(ListNode**phead,ListNode*new_node){ListNode*p=*phead;ListNode*prv=*phead;// 전 노드inti,cnt;if(*phead==NULL){p=NULL;}//헤더가 NULL일 경우else{cnt=0;while(p){if(p->data.id>new_node->data.id){break;}if(cnt>0)//전 노드는 한 바퀴 돈 후에 하나씩 증가prv=prv->link;p=p->link;cnt++;}//여기까지 들어갈 자리의 전 노드를 찾음if(cnt==0)// 들어갈 자리가 첫 번째 자리일 경우p=NULL;elsep=prv;}insert_node(phead,p,new_node);}voiddisplay(ListNode*phead){ListNode*p=phead;while(p){printf("%d %d %d\n",p->data.id,p->data.eng,p->data.math);p=p->link;}}
p가 NULL 일 때 (삽입 하려는 위치가 첫 번째 일 때, p는 선행 노드 이므로 p가 NULL이라는 말은 삽입하려는 위치가 첫 번째라는 말이다.)
마지막으로 나머지 경우의 수이다.
voidascending_insert_node(ListNode**phead,ListNode*new_node){ListNode*p=*phead;ListNode*prv=*phead;// 전 노드inti,cnt;if(*phead==NULL){p=NULL;}//헤더가 NULL일 경우else{cnt=0;while(p){if(p->data.id>new_node->data.id){break;}if(cnt>0)//전 노드는 한 바퀴 돈 후에 하나씩 증가prv=prv->link;p=p->link;cnt++;}//여기까지 들어갈 자리의 전 노드를 찾음if(cnt==0)// 들어갈 자리가 첫 번째 자리일 경우p=NULL;elsep=prv;}insert_node(phead,p,new_node);}
오름 차순 삽입의 핵심은 결국 들어 갈 위치를 찾는 문제 즉 선행 노드를 찾는게 핵심이다.
먼저 헤드 포인터가 NULL일 때는 일반 삽입과 같은 경우이다.
두 번째 경우인 첫 번째 자리에 들어갈 경우는 while(p)문 안에서 첫 번째 노드보다 데이터 값이 작은 경우이다. 그렇다면 첫 번째에 들어가야 하므로 p = NULL로 초기화 시켜준다.
마지막 경우는 prv를 두번 째 while(p) 부터 돌게하여 prv를 계속 이전 노드를 가리키게 한다.
결국 insert_node(phead, p, new_node); 는 각 해당하는 경우에 맞게 동작하게 된다.