바람이 머문 언덕
template 기능과 함수 포인트를 사용한 Double list 본문
// 리스트는 많이 사용하는 데이터 구조라 template 기능과 함수 포인트를 이용해서 만든 더블 리스트 입니다.
// 비교 함수와 노드 삭제 함수를 클래스 만들어서 클래서 생성시 전달 해주어야 합니다.
// template 기능을 사용하는 함수는 라이블리 파일로 만들 수 없고 소스 형태로 포함 되어야 합니다.
//예) struct data{ int day; char *memo; long money; long balance; unsigned long code; } ;
// struct node{ node *prev; data *dt; node *next; } ;
// static int cmpdata(data* n, data* d)
// { return (n->day==d->day) ? 0 : (n->day<d->day) ? -1 : 1; }
// static void delnode( node* temp)
// { if(temp->dt->memo) delete temp->dt->memo; delete temp->dt; delete temp; }
// Ndblist<node, data> *dblist;
// dblist= new Ndblist<node, data> (cmpnode, cmpdata);
// 더블 리스트 헤드 파일과 윈도우 API 함수로 만든 금전 출납부 소스 파일 입니다.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
typedef unsigned int UINT;
template<class N,class D> class Ndblist
{
public:
int ( *ftncmp)(D *,D * ); // 비교 함수 포인트
Ndblist( int ( *fcmp)(D *,D * ), void ( *ftdel)(N *)) ;
~Ndblist( ) { alldel(); }
void Setcmp(int (*fcmp)(D *,D *, int )) { ftncmp=fcmp; }
unsigned int count() { return icount; }
N *top() { return topnode; }
N *bottom() { return btmnode; }
/* N *makenode(D *dt)
{
N *istnode=new N;
if(istnode) istnode->dt=dt;
return istnode;
}*/
N *add(D *dt); //추가
void del( N *temp ); //노드 삭제
void alldel(); //리스트 삭제
void unnode( N *temp ); //노드 분리
// void pteorder(N *temp); //전위순회
// void inorder(N *temp); //중위 순회
void istprev( N *po, N *ist ); //po앞에 ist 삽입
void istnext( N *po, N *ist ); //po뒤에 ist 삽입
N *insertst(N * /*시작 포인터*/, D * /* 삽입 데이터*/, UINT &ic, N *istnode=NULL); //순차 삽입
int insertsh(N *&, D * , UINT &ic); //순차 검색
//void chposition(N *mv,N *po,int i=1);
protected:
/* void delnode( N *temp)
{
//delete[] temp->dt;delete[] temp->dt; delete temp;
}*/
N *btmnode, *topnode;
unsigned int icount; //현 항목 위치와 갯수
void ( *ftndel)(N *); // 노드 삭제 함수 포인트
};
template<class N,class D> Ndblist<N,D>::Ndblist(int ( *fcmp)(D *,D * ), void ( *ftdel)(N *))
{
btmnode=topnode=NULL; icount=0; ftncmp=fcmp; ftndel=ftdel;
}
template<class N,class D>N *Ndblist<N,D>::add(D *dt)
{
//N *istnode=
N *istnode=new N;
// if(istnode) istnode->dt=dt;//makenode(dt);
if(istnode)
{
istnode->dt=dt;
if(btmnode)
{
istnode->prev=topnode; istnode->next=topnode->next;
topnode->next=istnode;
}
else
{
btmnode=istnode;
istnode->prev=istnode->next=NULL;
}
topnode=istnode; ++icount;
}
return istnode;
}
template<class N,class D> void Ndblist<N,D>::istprev( N *po, N *ist )
{
ist->prev=po->prev; ist->next=po; icount++;
(po->prev) ? po->prev->next=ist : btmnode=ist;
po->prev=ist;
}
template<class N,class D> void Ndblist<N,D>::istnext( N *po, N *ist)
{
ist->prev=po; ist->next=po->next; icount++;
(po->next) ? po->next->prev=ist : topnode=ist;
po->next=ist;
}
template<class N,class D> void Ndblist<N,D>::unnode( N *temp )//
{
icount--;
if(temp->next) temp->next->prev=temp->prev;
else topnode=temp->prev;
(temp->prev) ? temp->prev->next=temp->next : btmnode=temp->next;
}
template<class N,class D> void Ndblist<N,D>::del( N *temp )//
{
unnode(temp ); (*ftndel)(temp);
}
template<class N,class D> void Ndblist<N,D>::alldel()//
{
N *temp=btmnode;
while(temp)
{
btmnode=temp->next;
(*ftndel)(temp);
temp=btmnode;
}
icount=0;
btmnode=topnode=NULL;
}
template<class N,class D> N *Ndblist<N,D>::insertst( N *po, D *dt , UINT &ic, N *istnode)
{
// ic= 갯수 i 같은 것이 있을 때 k 비교,
int s;
if(!istnode) istnode=new N;//makenode(dt);
if(istnode)
{
istnode->dt=dt;
if(btmnode)
{
if(po==NULL) { po=topnode; ic=icount; }
s=insertsh(po, dt, ic);
if(s==-1) { istprev(po, istnode ); }
else //if((s==1) || (s==0)) }// 크거나 같은 것이 있으면
{
ic++; istnext(po, istnode );
}
}
else
{
btmnode=topnode=istnode;
ic=icount=1; //s=0;
istnode->prev=istnode->next=NULL;
}
}
return istnode;
}
template<class N,class D> int Ndblist<N,D>::insertsh(N *&temp, D *dt, UINT &ic) // 순차 검색 ?
{
int s=0, i=0;
while(temp)
{
i=(*ftncmp)(dt, temp->dt);
if(i==-1) // 작으면
{
if((s>0) || (!temp->prev)) break;
else
{
s=-1; ic--; temp=temp->prev;
}
}
else if(i==1) // 크면
{
if((s<0) || (!temp->next)) break;
else { s=1; ic++; temp=temp->next; }
}
else break; //(i == 0) 같으면
}
return i;
}