void PecahList (List *L1, List *L2, List L)
/* I.S. L mungkin kosong */
/* F.S. Berdasarkan L, dibentuk dua buah list L1 dan L2 */
/* L tidak berubah: untuk membentuk L1 dan L2 harus alokasi */
/* L1 berisi separuh elemen L dan L2 berisi sisa elemen L */
/* Jika elemen L ganjil, maka separuh adalah NbElmt(L) div 2 */
{
	addressList P = First(L), PPecah;
	int count = 0, half = NbElmt(L) / 2, success = 1;
	
	CreateEmptyList(L1);
	CreateEmptyList(L2);
	
	while (P != NULL && success) {
		count++;
		PPecah = Alokasi(Info(P));
		if (PPecah != NULL) {
			if (count <= half) {
				InsertLast(L1, PPecah);
			} else {
				InsertLast(L2, PPecah);
			}
		} else {
			success = 0;
		}
		
		P = Next(P);
	}
	
	if (!success) {
		DelAll(L1);
		DelAll(L2);
    }
}
int main()
{
   List L1, L2;
   Stack S1, S2;
   Position current1, current2;
   FILE *fpr, *fpi;
   Position current;
   int isPalindrome;

   L1 = CreateEmptyList();
   fpr = fopen("linkedlist1.dat", "r");
   if(fpr == NULL)
   {
      printf("\nFailed to open file!\n");
   }
   CreateList(fpr, L1);

   L2 = CreateEmptyList();
   fpi = fopen("linkedlist2.dat", "r");
   if(fpi == NULL)
   {
      printf("\nFailed to open file!\n");
      exit(0);
   }
   CreateList(fpi, L2);

   PrintList(L1);
   PrintList(L2);

   S1 = CreateEmptyStack();
   S1 = CreateStackFromList(L1, S1);

   S2 = CreateEmptyStack();
   S2 = CreateStackFromList(L2, S2);
   
   PrintStack(S1);
   PrintStack(S2);

   isPalindrome = CheckIsPalindrome(L1, S1);
   if(isPalindrome == 0)
   {
      printf("\nThat list is a Palindrome!\n");
   }
   else
   {
      printf("\nThat list is not a Palindrome!\n");
   }

   isPalindrome = CheckIsPalindrome(L2, S2);
   if(isPalindrome == 0)
   {
      printf("\nThat list is a Palindrome!\n");
   }
   else
   {
      printf("\nThat list is not a Palindrome!\n");
   }

   return 0;
}
List FCopyList (List L)
/* Mengirimkan list yang merupakan salinan L */
/* dengan melakukan alokasi. */
/* Jika ada alokasi gagal, hasilnya list kosong dan */
/* semua elemen yang terlanjur di-alokasi, harus didealokasi */
{
	List CopiedList;
	addressList CopyP, P = First(L);
	int success = 1;
	
	CreateEmptyList(&CopiedList);
	
	while (P != NULL && success) {
		CopyP = Alokasi(Info(P));
		if (CopyP != NULL) {
			InsertLast(&CopiedList, CopyP);
			P = Next(P);
		} else {
			success = 0;
		}
	}
	
	if (!success)
		DelAll(&CopiedList);

	return CopiedList;
}
List FInversList (List L)
/* Mengirimkan list baru, hasil invers dari L */
/* dengan menyalin semua elemn list. Alokasi mungkin gagal. */
/* Jika alokasi gagal, hasilnya list kosong */
/* dan semua elemen yang terlanjur di-alokasi, harus didealokasi */
{
	List InversedList;
	addressList InversP, P = First(L);
	int success = 1;
	
	CreateEmptyList(&InversedList);
	
	while (P != NULL && success) {
		InversP = Alokasi(Info(P));
		if (InversP != NULL) {
			InsertFirst(&InversedList, InversP);
			P = Next(P);
		} else {
			success = 0;
		}
	}
	
	if (!success)
		DelAll(&InversedList);

	return InversedList;
}
void Konkat (List L1, List L2, List * L3)
/* I.S. L1 dan L2 sembarang */
/* F.S. L1 dan L2 tetap, L3 adalah hasil konkatenasi L1 & L2 */
/* Jika semua alokasi berhasil, maka L3 adalah hasil konkatenasi */
/* Jika ada alokasi yang gagal, semua elemen yang sudah dialokasi */
/* harus di-dealokasi dan L3=NULL */
/* Konkatenasi dua buah list : L1 & L2 menghasilkan L3 yang "baru" */
/* Elemen L3 adalah hasil alokasi elemen yang “baru”. */
/* Jika ada alokasi yang gagal, maka L3 harus bernilai NULL */
/* dan semua elemen yang pernah dialokasi didealokasi */
{
	addressList PKonkat, P;
	int success = 1;
	
	CreateEmptyList(L3);
	
    P = First(L1);
	while (P != NULL && success) {
		PKonkat = Alokasi(Info(P));
		if (PKonkat != NULL) {
			InsertLast(L3, PKonkat);
			P = Next(P);
		} else {
			success = 0;
		}
	}
	P = First(L2);
	while (P != NULL && success) {
		PKonkat = Alokasi(Info(P));
		if (PKonkat != NULL) {
			InsertLast(L3, PKonkat);
			P = Next(P);
		} else {
			success = 0;
		}
	}
	
	if (!success)
		DelAll(L3);
}
void Konkat1(List *L1, List *L2, List *L3)
/* I.S. L1 dan L2 sembarang */
/* F.S. L1 dan L2 kosong, L3 adalah hasil konkatenasi L1 & L2 */
/* Konkatenasi dua buah list : L1 dan L2 */
/* menghasilkan L3 yang baru (dengan elemen list L1 dan L2) */
/* dan L1 serta L2 menjadi list kosong. */
/* Tidak ada alokasi/dealokasi pada prosedur ini */
{
    CreateEmptyList(L3);
    if (IsEmptyList(*L1))
    {
        First(*L3) = First(*L2);
    }
    else
    {
        First(*L3) = First(*L1);
        addressList Last1 = First(*L1);
        while (Next(Last1) != NULL)
            Last1 = Next(Last1);
        Next(Last1) = First(*L2);
    }
    First(*L1) = First(*L2) = NULL;
}