pete wrote:
Quote:
pete wrote:
Quote:
pete wrote:
Quote:
pete wrote:
mekaju2001@gmail.com wrote:
On Jan 3, 10:27 am, pete <pfil...@mindspring.comwrote:
dmp wrote:
What areLinkedlist?
Please somebody show some ready made programs oflinkedlist
Here are two:
http://www.mindspring.com/~pfilandr/.../string_sort.c http://www.mindspring.com/~pfilandr/...les/list_lib.c
I think you have a link quoting problem.
Here are five ready made programs of linked list:
string_sort_2.c
Lf_sort_2.c
file_sort_2.c
file_parse_2.c
file_collate_2
I'll post the first one here, and then the rest as replies.
string_sort_2.c sorts strings by length because that's
a simple way to show the stability of the sorting function.
/* BEGIN string_sort_2.c */
>
Lf_sort_2.c is almost the same program,
with long doubles instead of strings
using most of the same generic list functions.
>
/* BEGIN Lf_sort_2.c */
After that, file_sort_2.c, and file_parse_2.c
are both homework problems posted to clc.
file_sort_2.c introduces the get_line function.
/* BEGIN file_sort_2.c */
file_collate_2.c is interesting because it has a list of lists.
/* BEGIN file_collate_2.c */
/*
** Program reads files of customer names
** and products purchased.
** Some files may have identical customers
** with some same purchases as other files.
** Program makes a list of purchased products
** and who has purchased them.
** Demonstrates use of the list_collate function
** on list of lists.
** Both of the macros, NFILES and MAX_PRODUCTS_PER_FILE
** can be changed to any positive value
** without having to alter any other part of the program.
** Also, the number of strings in the
** NAMES and PRODUCT_NAMES macros, can be changed
** without having to alter any other part of the program.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define NFILES 6
#define MAX_PRODUCTS_PER_FILE 4
#define NAMES \
{"Ms Smith","Mr. Jones","Ms Brown","Mr. Green","Ms Grant"}
#define PRODUCT_NAMES \
{"milk","candy","meat","juice","fruit",\
"eggs","cereal","coffee","tea","gum",\
"bread","ketchup","salt","pepper","sugar"}
#define LFSM ("") /* (List File Start Marker) */
#define LU_RAND_SEED 123456LU
#define LU_RAND(S) ((S) * 69069 + 362437 & 0XFFFFFFFFLU)
#define NMEMB(A) (sizeof (A) / sizeof *(A))
typedef struct list_node {
struct list_node *next;
void *data;
} list_type;
typedef struct {
char *product_name;
list_type *consumers;
} purchases;
void product_free(void *data);
list_type *product_list(const list_type *head);
void prod_merge(list_type *head);
void cons_merge(list_type *head);
int prod_cmp(const list_type *a, const list_type *b);
int cons_cmp(const list_type *a, const list_type *b);
int product_display(const list_type *head, FILE *stream);
int consumer_display(const list_type *head, FILE *stream);
long unsigned shuffle
(long unsigned *array, long unsigned n, long unsigned seed);
int get_line(char **lineptr, size_t *n, FILE *stream);
list_type *list_append
(list_type **head, list_type *tail, void *data, size_t size);
void list_free(list_type *node, void (*free_data)(void *));
list_type *list_sort(list_type *head,
int (*compar)(const list_type *, const list_type *));
list_type *list_merge(list_type *head, list_type *tail,
int (*compar)(const list_type *, const list_type *));
void list_collate(list_type *node,
int (*compar)(const list_type *, const list_type *),
void (*data_merge)(list_type *));
static list_type *sort_node (list_type *head,
int (*compar)(const list_type *, const list_type *));
static list_type *merge_lists(list_type *head, list_type *tail,
int (*compar)(const list_type *, const list_type *));
static list_type *split_list(list_type *head);
int main(void)
{
long unsigned index, line;
int rc;
char *buff;
size_t size;
list_type *tail, *head, *product;
char fn[L_tmpnam];
FILE *fp;
long unsigned lu_seed = LU_RAND_SEED;
char *name[] = NAMES;
char *product_name[] = PRODUCT_NAMES;
long unsigned number[NMEMB(product_name)];
const size_t LFSM_size = 1 + strlen(LFSM);
const long unsigned n_files = NFILES;
const long unsigned mppf
= MAX_PRODUCTS_PER_FILE NMEMB(product_name)
? NMEMB(product_name) : MAX_PRODUCTS_PER_FILE;
puts("/* BEGIN file_collate_2.c output */");
puts("\nInput: Customer purchase record files");
/*
** Open temporary input text files for writing.
*/
size = 0;
buff = NULL;
head = tail = NULL;
tmpnam(fn);
for (index = 0; index != n_files; ++index) {
fp = fopen(fn, "w");
if (fp == NULL) {
fputs("fopen(fn, \"w\") == NULL\n", stderr);
break;
}
/*
** Write to standard output,
** as well as to temporary input text files.
*/
fprintf(stdout, "%s\n ", name[lu_seed % NMEMB(name)]);
fprintf( fp, "%s\n" , name[lu_seed % NMEMB(name)]);
lu_seed = shuffle(number, NMEMB(number), lu_seed);
line = lu_seed % mppf + 1;
while (line-- != 0) {
fprintf(stdout, " %s,", product_name[number[line]]);
fprintf( fp, "%s\n", product_name[number[line]]);
}
puts("\b ");
/*
** Close each file after writing.
*/
fclose(fp);
/*
** Mark the start of each file in the list.
** (List File Start Marker)(LFSM)
*/
tail = list_append(&head, tail, LFSM, LFSM_size);
if (tail == NULL) {
fputs("tail == NULL_1\n", stderr);
break;
}
/*
** Open input text files for reading.
*/
fp = fopen(fn, "r");
if (fp == NULL) {
fputs("fopen(fn, \"r\") == NULL\n", stderr);
break;
}
/*
** Represent each line of each input text file
** as a string in a node of a linked list.
*/
while ((rc = get_line(&buff, &size, fp)) 0) {
/*
** Make sure that the List File Start Marker
** isn't showing up where it's not supposed to.
*/
if (strcmp(LFSM, buff) == 0) {
fputs("strcmp(LFSM, buff) == 0\n", stderr);
break;
}
tail = list_append(&head, tail, buff, strlen(buff) + 1);
if (tail == NULL) {
fputs("tail == NULL_2\n", stderr);
break;
}
}
/*
** Close each temp input file after reading.
*/
fclose(fp);
if (rc != EOF) {
fprintf(stderr, "rc == %d\n", rc);
break;
}
}
/*
** Free allocated buffer used by get_line function.
** Remove temp input file.
*/
free(buff);
remove(fn);
/*
** Create list of product_names,
** with each product having a list of consumers.
** Free file list.
*/
product = product_list(head);
list_free(head, free);
/*
** Display list.
** Free list.
*/
puts("\n\nOutput: Product consumer list");
product_display(product, stdout);
list_free(product, product_free);
puts("\n/* END file_collate_2.c output */");
return 0;
}
void product_free(void *data)
{
purchases *const ptr = data;
list_free(ptr -consumers, free);
free(ptr -product_name);
free(ptr);
}
list_type *product_list(const list_type *head)
{
purchases temp;
size_t size;
size_t c_size;
char *consumer;
list_type *c_tail = NULL;
list_type *product = NULL;
list_type *p_tail = NULL;
/*
** Make a list of structures.
** Each structure will have a pointer to the name of a product
** from an input text file and also a pointer to a list
** with one node that contains a pointer
** to the customer name from the file.
**
** (head) list format:
** LFSM marks the begining of new file entry in list.
** First line of each file is customer name;
** Arbitrary number of subsequent lines are product names;
** Then, either the list ends or...
** LFSM marks the begining of new file entry in list.
*/
while (head != NULL) {
if (strcmp(head -data, LFSM) == 0) {
head = head -next;
if (head != NULL) {
consumer = head -data;
c_size = strlen(consumer) + 1;
head = head -next;
}
continue;
}
size = strlen(head -data) + 1;
temp.product_name = malloc(size);
if (temp.product_name == NULL) {
fputs("temp.product_name == NULL\n", stderr);
list_free(temp.consumers, free);
list_free(product, product_free);
product = NULL;
break;
}
memcpy(temp.product_name, head -data, size);
temp.consumers = NULL;
c_tail =
list_append(&temp.consumers, c_tail, consumer, c_size);
if (c_tail == NULL) {
fputs("c_tail == NULL\n", stderr);
list_free(temp.consumers, free);
list_free(product, product_free);
product = NULL;
break;
}
p_tail = list_append(&product, p_tail, &temp, sizeof temp);
if (p_tail == NULL) {
fputs("p_tail == NULL\n", stderr);
list_free(temp.consumers, free);
list_free(product, product_free);
product = NULL;
break;
}
head = head -next;
}
/*
** (product) is a pointer to a list of structures,
** with each stucture containing
** a pointer to a product name and
** a pointer to a list of consumer names that only has one node.
** Each structure, at this point,
** represents the purchase of each individual item:
** the product,
** and the person who bought it.
** Sort the list by product name.
*/
product = list_sort(product, prod_cmp);
/*
** The list_collate function operates on a sorted list.
** In this call, list_collate will merge the
** lists of customer names of nodes
** which have the same product names.
** The merged list is assigned to one node
** and the other node is deleted.
** Nodes with duplicate customer names
** in the resulting merged list,
** are deleted by another call to list_collate,
** from within prod_merge.
*/
list_collate(product, prod_cmp, prod_merge);
/*
** Each structure, at this point,
** represents each different purchased product,
** and all of the different people who bought it.
*/
return product;
}
void prod_merge(list_type *head)
{
purchases *data = head -data;
list_type *next = head -next;
purchases *next_data = next -data;
data -consumers = list_merge
(data -consumers, next_data -consumers, cons_cmp);
list_collate(data -consumers, cons_cmp, cons_merge);
free(next_data -product_name);
free(next_data);
}
void cons_merge(list_type *head)
{
free(head -next -data);
}
int prod_cmp(const list_type *a, const list_type *b)
{
purchases *const a_ptr = a -data;
purchases *const b_ptr = b -data;
return strcmp(a_ptr -product_name, b_ptr -product_name);
}
int cons_cmp(const list_type *a, const list_type *b)
{
return strcmp(a -data, b -data);
}
int product_display(const list_type *head, FILE *stream)
{
int rc = 0;
while (head != NULL) {
purchases *const ptr = head -data;
rc = fprintf(stream, "Product: %s\nConsumers:",
ptr -product_name);
if (0 rc) {
break;
}
rc = consumer_display(ptr -consumers, stream);
if (0 rc) {
break;
}
head = head -next;
}
return rc;
}
int consumer_display(const list_type *head, FILE *stream)
{
int rc = 0;
while (head != NULL) {
rc = fprintf(stream," %s," , head -data);
if (0 rc) {
break;
}
head = head -next;
}
if (rc 0) {
rc = fputs("\b \n\n", stream);
}
return rc;
}
long unsigned shuffle
(long unsigned *array, long unsigned n, long unsigned seed)
{
long unsigned i, r;
array[0] = 0;
for (i = 1; n i; ++i) {
seed = LU_RAND(seed);
r = seed % (i + 1);
array[i] = 0;
array[i] = array[r];
array[r] = i;
}
return seed;
}
int get_line(char **lineptr, size_t *n, FILE *stream)
{
int rc;
void *p;
size_t count;
count = 0;
while ((rc = getc(stream)) != EOF) {
++count;
if (count == (size_t)-2) {
if (rc != '\n') {
(*lineptr)[count] = '\0';
(*lineptr)[count - 1] = (char)rc;
} else {
(*lineptr)[count - 1] = '\0';
}
break;
}
if (count + 2 *n) {
p = realloc(*lineptr, count + 2);
if (p == NULL) {
if (*n count) {
if (rc != '\n') {
(*lineptr)[count] = '\0';
(*lineptr)[count - 1] = (char)rc;
} else {
(*lineptr)[count - 1] = '\0';
}
} else {
if (*n != 0) {
**lineptr = '\0';
}
ungetc(rc, stream);
}
count = 0;
break;
}
*lineptr = p;
*n = count + 2;
}
if (rc != '\n') {
(*lineptr)[count - 1] = (char)rc;
} else {
(*lineptr)[count - 1] = '\0';
break;
}
}
if (rc != EOF) {
rc = INT_MAX count ? count : INT_MAX;
} else {
if (*n count) {
(*lineptr)[count] = '\0';
}
}
return rc;
}
list_type *list_append
(list_type **head, list_type *tail, void *data, size_t size)
{
list_type *node;
node = malloc(sizeof *node);
if (node != NULL) {
node -next = NULL;
node -data = malloc(size);
if (node -data != NULL) {
memcpy(node -data, data, size);
if (*head != NULL) {
tail -next = node;
} else {
*head = node;
}
} else {
free(node);
node = NULL;
}
}
return node;
}
void list_free(list_type *node, void (*free_data)(void *))
{
list_type *next_node;
while (node != NULL) {
next_node = node -next;
free_data(node -data);
free(node);
node = next_node;
}
}
list_type *list_sort(list_type *head,
int (*compar)(const list_type *, const list_type *))
{
return head != NULL ? sort_node(head, compar) : head;
}
list_type *list_merge(list_type *head, list_type *tail,
int (*compar)(const list_type *, const list_type *))
{
if (tail != NULL) {
if (head != NULL) {
head = merge_lists(head, tail, compar);
} else {
head = tail;
}
}
return head;
}
void list_collate(list_type *node,
int (*compar)(const list_type *, const list_type *),
void (*data_merge)(list_type *))
{
list_type *next_node;
if (node != NULL) {
next_node = node -next;
while (next_node != NULL) {
if (compar(node, next_node) == 0) {
data_merge(node);
node -next = next_node -next;
free(next_node);
} else {
node = next_node;
}
next_node = node -next;
}
}
}
static list_type *sort_node(list_type *head,
int (*compar)(const list_type *, const list_type *))
{
list_type *tail;
if (head -next != NULL) {
tail = split_list(head);
tail = sort_node(tail, compar);
head = sort_node(head, compar);
head = merge_lists(head, tail, compar);
}
return head;
}
static list_type *split_list(list_type *head)
{
list_type *tail;
tail = head -next;
while ((tail = tail -next) != NULL
&& (tail = tail -next) != NULL)
{
head = head -next;
}
tail = head -next;
head -next = NULL;
return tail;
}
static list_type *merge_lists(list_type *head, list_type *tail,
int (*compar)(const list_type *, const list_type *))
{
list_type *list, *sorted, **node;
node = compar(head, tail) 0 ? &tail : &head;
list = sorted = *node;
*node = sorted -next;
while (*node != NULL) {
node = compar(head, tail) 0 ? &tail : &head;
sorted -next = *node;
sorted = *node;
*node = sorted -next;
}
sorted -next = tail != NULL ? tail : head;
return list;
}
/* END file_collate_2.c */
--
pete