xlib_playground

Xlib playground for experiments.
Log | Files | Refs

list.c (3930B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #include "list.h"
      5 
      6 
      7 static int __lqsort(List *p, List *tail,
      8 	int (* cmp)(void *, void *));
      9 static void __lprint(List *p, List *tail, void (* pfnc)(void *));
     10 
     11 static int list_count = 0;
     12 
     13 /*
     14  * Laddfront() adds item in front of List p.
     15  * Returns NULL if error occured.
     16  */
     17 List *
     18 laddfront(List *p, void *item)
     19 {
     20 	if (item == NULL) {
     21 		// TODO: should print some message ??
     22 		//fprintf(stderr, "laddfront: Error. Item is NULL\n");
     23 		return NULL;
     24 	}
     25 
     26 	List *newlp;
     27 	if((newlp = (List *)malloc(sizeof(List))) == NULL) {
     28 		fprintf(stderr, "laddfront: Error. Could not allocate memory.\n");
     29 		return NULL;
     30 	}
     31 	list_count++;
     32 	newlp->item = item;
     33 	newlp->next = p;
     34 	return newlp;
     35 }
     36 
     37 /*
     38  * Lfree() frees List *p. Its items should be freed elsewhere.
     39  */
     40 void
     41 lfree(List *p)
     42 {
     43 	List *q;
     44 	for (q = p; q != NULL; q = p) {
     45 		p = q->next;
     46 		free(q);
     47 		list_count--;
     48 	}
     49 }
     50 
     51 /*
     52  * Lfreei() frees List *p. Its items are freed using ifree().
     53  */
     54 void
     55 lfreei(List *p, void (* ifree)(void *))
     56 {
     57 	List *q;
     58 	for (q = p; q != NULL; q = p) {
     59 		p = q->next;
     60 		ifree(q->item);
     61 		free(q);
     62 		list_count--;
     63 	}
     64 }
     65 
     66 int
     67 get_list_count(void)
     68 {
     69 	return list_count;
     70 }
     71 
     72 void
     73 lprint(List *p, void (* pfnc)(void *))
     74 {
     75 	__lprint(p, NULL, pfnc);
     76 }
     77 
     78 void
     79 __lprint(List *p, List *tail, void (* pfnc)(void *))
     80 {
     81 	if (p == NULL) {
     82 		printf("\n");
     83 	}
     84 	for (;p != tail && p != NULL; p = p->next) {
     85 		if (p->item == NULL) {
     86 			fprintf(stderr, "__lprint: Error. Item is NULL\n");
     87 			return;
     88 		}
     89 		(*pfnc)(p->item);
     90 		printf("%s", p->next == tail ? "\n" : "->");
     91 	}
     92 	if (p != tail) {
     93 		fprintf(stderr, "__lprint: Warning. Tail not found in the list.\n");
     94 	}
     95 }
     96 
     97 /*
     98  * Bubble sort. returns -1 if error occured, 0 if succeed.
     99  */
    100 int
    101 lbsort(List *p, int (* cmp)(void *, void *))
    102 {
    103 	List *q;
    104 
    105 	for (;p != NULL && p->next != NULL; p = p->next) {
    106 		for (q = p->next; q != NULL; q = q->next) {
    107 			if (p->item == NULL || q->item == NULL) {
    108 				fprintf(stderr, "lbsort: Error. List without item.\n");
    109 				return -1;
    110 			}
    111 			if (cmp(p->item, q->item) > 0) {
    112 				lswap(p, q);
    113 			}
    114 		}
    115 	}
    116 	return 0;
    117 }
    118 
    119 /*
    120  * Quick sort
    121  * Lqsort() sorts entire List p, according to the results of cmp().
    122  * __lqsort() sorts the List from p to the item before tail.
    123  * Tail can be NULL. This case __lqsort() sorts entire List.
    124  * Returns 0 if succeed, -1 if error occured.
    125  */
    126 int
    127 lqsort(List *p, int (* cmp)(void *, void *))
    128 {
    129 	return __lqsort(p, NULL, cmp);
    130 }
    131 
    132 static int
    133 __lqsort(List *p, List *tail, int (* cmp)(void *, void *))
    134 {
    135 	if (p == tail || p->next == tail)
    136 		return 0;
    137 
    138 	List *pivot, *q, *last;
    139 	int i;
    140 
    141 	/* select the pivot randomly */
    142 	for (i = 0, q = p; q != tail; q = q->next) {
    143 		if (rand() % ++i == 0)
    144 			pivot = q;
    145 	}
    146 
    147 	lswap(p, pivot);
    148 	last = p;
    149 	for (q = p->next; q != tail; q = q->next) {
    150 		if (p->item == NULL || q->item == NULL) {
    151 			fprintf(stderr, "lbsort: Error. List without item.\n");
    152 			return -1;
    153 		}
    154 		if (cmp(p->item, q->item) > 0) {
    155 			last = last->next;
    156 			lswap(last, q);
    157 		}
    158 	}
    159 	lswap(p, last);
    160 
    161 	__lqsort(last->next, tail, cmp);
    162 	__lqsort(p, last, cmp);
    163 
    164 	return 0;
    165 }
    166 
    167 void
    168 lswap(List *p, List *q)
    169 {
    170 	if (p == NULL || q == NULL)
    171 		return;
    172 	void *tmp;
    173 	tmp = p->item;
    174 	p->item = q->item;
    175 	q->item = tmp;
    176 }
    177 
    178 /*
    179  * Leqa() returns 1 if two Lists are identicall, 0 if not.
    180  * Only checks the address of each items.
    181  */
    182 int
    183 leqa(List *p, List *q)
    184 {
    185 	for (;p != NULL && q != NULL; p = p->next, q = q->next) {
    186 		if (p->item != q->item)
    187 			return 0;
    188 	}
    189 	if (p == NULL && q == NULL)
    190 		return 1;
    191 	return 0;
    192 }
    193 
    194 /*
    195  * Leqi() returns 1 if two Lists are identicall, 0 if not.
    196  * Compares each items with eq().
    197  */
    198 int
    199 leqi(List *p, List *q, int (*eq)(void *, void*))
    200 {
    201 	for (;p != NULL && q != NULL; p = p->next, q = q->next) {
    202 		if (!eq(p->item, q->item))
    203 			return 0;
    204 	}
    205 	if (p == NULL && q == NULL)
    206 		return 1;
    207 	return 0;
    208 }
    209 
    210 unsigned long int
    211 llen(List *p)
    212 {
    213 	unsigned long len = 0;
    214 	for (; p != NULL; p = p->next)
    215 		len++;
    216 	return len;
    217 }