473,396 Members | 1,877 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Better Linked List Handling

Just finished a new IBM DeveloperWorks article on linked lists, and
thought you all might be interested. It's not an introduction -- it
instead covers some of the more interesting aspects of linked lists.

http://www.ibm.com/developerworks/li...ry/l-listproc/

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017
Nov 14 '05 #1
12 2483
On Thu, 06 Jan 2005 11:42:16 -0500, Jonathan Bartlett
<jo*****@eskimo.com> wrote:
Just finished a new IBM DeveloperWorks article on linked lists, and
thought you all might be interested. It's not an introduction -- it
instead covers some of the more interesting aspects of linked lists.

http://www.ibm.com/developerworks/li...ry/l-listproc/


Maybe you want to run it through a good lint processor to eliminate
the undefined behavior. While you are at it, you might also get rid
of the useless cast which serves only as a bad example.
<<Remove the del for email>>
Nov 14 '05 #2
Jonathan Bartlett wrote:
Just finished a new IBM DeveloperWorks article on linked lists, and
thought you all might be interested. It's not an introduction -- it
instead covers some of the more interesting aspects of linked lists.

http://www.ibm.com/developerworks/li...ry/l-listproc/


I like the emphasis on Scheme, and the explanation of tail-sharing.
Defining NULL as 0 might confuse some people, although it's quite
correct (see the comp.lang.c FAQ question 5.5 and related); it's safe to
assume they know about NULL.

There's also a better way to do the generic linked list data structure,
assuming that the value in each node is fixed (read-only): by placing
the next pointer first, then allocating just enough for the specific
data object, you can save space (allocate
offsetof(data)+sizeof(whatever)). The read-only restriction isn't too
big of a deal, since you can cut out an old node and put in a new one.

The tags are also quite wasteful of space, since most lists are of data
of a single type; for these list it's better to put the tag in the
list's data structure. If you are really interested in heterogenous
lists, one effective approach is to allocate the nodes out of pools,
where each pool only contains data of one type. You can determine which
pool an object is in by pointer comparison. Then you have a small table
mapping pool number to tag. As pools fill up you make more (getting
larger as you make more) and expand the table.

Finally, I think cdr coding and unrolled linked lists definitely deserve
a mention - these are two common solutions to the nasty space overhead
and cache problems associated with simple linked lists, although they
complicate some operations.
--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Nov 14 '05 #3
Barry Schwarz wrote:
<jo*****@eskimo.com> wrote:
Just finished a new IBM DeveloperWorks article on linked lists, and
thought you all might be interested. It's not an introduction -- it
instead covers some of the more interesting aspects of linked lists.

http://www.ibm.com/developerworks/li...ry/l-listproc/


Maybe you want to run it through a good lint processor to eliminate
the undefined behavior. While you are at it, you might also get rid
of the useless cast which serves only as a bad example.


Looks to me as if he has largely renamed lisp as scheme, and
avoided giving credit.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #4
Jonathan Bartlett wrote:

Just finished a new IBM DeveloperWorks article on linked lists, and
thought you all might be interested. It's not an introduction -- it
instead covers some of the more interesting aspects of linked lists.

http://www.ibm.com/developerworks/li...ry/l-listproc/


You have:

Listing 4. Linked list using generic nodes

struct generic_node {
data the_data;
struct generic_node *next;
};

.... but
struct generic_node {
void *data;
struct generic_node *next;
};

is really more generic.
It's especially useful if data points to a structure
which has pointers to lists with different types of data.

struct generic_node *list_rev(struct generic_node *head)
{
struct generic_node *previous, *next_node;

if (head != NULL) {
next_node = NULL;
while (head -> next != NULL) {
previous = head;
head = previous -> next;
previous -> next = next_node;
next_node = previous;
}
head -> next = next_node;
}
return head;
}

void list_free(struct generic_node *node, void (*free_data)(void *))
{
struct generic_node *next_node;

while (node != NULL) {
next_node = node -> next;
free_data(node -> data);
free(node);
node = next_node;
}
}

struct generic_node *list_sort(struct generic_node *head,
int (*compar)(const struct generic_node *,
const struct generic_node *))
{
return node_sort(head, list_count(head), compar);
}

size_t list_count(struct generic_node *head)
{
size_t count;

for (count = 0; head != NULL; head = head -> next) {
++count;
}
return count;
}

struct generic_node *node_sort(struct generic_node *head, size_t count,
int (*compar)(const struct generic_node *,
const struct generic_node *))
{
size_t half;
struct generic_node *tail;

if (count > 1) {
half = count / 2;
tail = list_split(head, half);
tail = node_sort(tail, count - half, compar);
head = node_sort(head, half, compar);
head = list_merge(head, tail, compar);
}
return head;
}

struct generic_node *list_split(struct generic_node *head, size_t count)
{
struct generic_node *tail;

while (count-- > 1) {
head = head -> next;
}
tail = head -> next;
head -> next = NULL;
return tail;
}

struct generic_node *list_merge(struct generic_node *head, struct
generic_node *tail,
int (*compar)(const struct generic_node *,
const struct generic_node *))
{
struct generic_node *list, *sorted, **node;

node = compar(head, tail) > 0 ? &tail : &head;
sorted = list = *node;
*node = sorted -> next;
while (*node != NULL) {
node = compar(head, tail) > 0 ? &tail : &head;
sorted -> next = *node;
sorted = sorted -> next;
*node = sorted -> next;
}
sorted -> next = head != NULL ? head : tail;
return list;
}

int list_sorted(struct generic_node *list,
int (*compar)(const struct generic_node *,
const struct generic_node *))
{
if (list != NULL) {
while (list -> next != NULL) {
if (compar(list, list -> next) > 0) {
break;
}
list = list -> next;
}
}
return list == NULL || list -> next == NULL;
}
Nov 14 '05 #5
Derrick Coetzee <dc****@moonflare.com> writes:
[...]
Defining NULL as 0 might confuse some people, although it's quite
correct (see the comp.lang.c FAQ question 5.5 and related); it's
safe to assume they know about NULL.

[...]

Actually, defining NULL at all in user code is a bad idea.
Just #include <stdlib.h>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #6
CBFalconer <cb********@yahoo.com> writes:
[...]
Looks to me as if he has largely renamed lisp as scheme, and
avoided giving credit.


Actually, Scheme is a well known Lisp dialect. It was developed in
the 1970s.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #7
pete wrote:
struct generic_node {
data the_data;
struct generic_node *next;
};

... but

struct generic_node {
void *data;
struct generic_node *next;
};

is really more generic.


Neither is typesafe, but the first has the notable advantage of internal
storage, which for the small data the author considers is quite a
significant advantage in space overhead (especially with your typical
high-overhead memory allocator), as well as having cache benefits and
saving lots of dereferences.

It's also relatively simple to have a linked list datatype generic to
all data types and also using internal storage (and typesafe too), by
using macro-generated inline functions as an interface to a library of
linked list functions parameterized by data size.
--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Nov 14 '05 #8
Keith Thompson wrote:
CBFalconer <cb********@yahoo.com> writes:
[...]
Looks to me as if he has largely renamed lisp as scheme, and
avoided giving credit.


Actually, Scheme is a well known Lisp dialect. It was developed
in the 1970s.


Oh. As you can see, I do not follow Lisp closely.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #9
Someone on the Scheme list said that the article series is like a HOWTO
for Greenspun's tenth law of programming :)

Nov 14 '05 #10
On Fri, 07 Jan 2005 05:30:20 GMT, CBFalconer <cb********@yahoo.com>
wrote:
Barry Schwarz wrote:
<jo*****@eskimo.com> wrote:
Just finished a new IBM DeveloperWorks article on linked lists, and
thought you all might be interested. It's not an introduction -- it
instead covers some of the more interesting aspects of linked lists.

http://www.ibm.com/developerworks/li...ry/l-listproc/


Maybe you want to run it through a good lint processor to eliminate
the undefined behavior. While you are at it, you might also get rid
of the useless cast which serves only as a bad example.


Looks to me as if he has largely renamed lisp as scheme, and
avoided giving credit.


Scheme is a lisp derivative, but it's been around since 1975. It's
much smaller than Lisp, and the OP doesn't claim to have invented it.
Another such was named Plan - I remember a paper entitled "Why
Planning is Better Than Scheming." Or maybe the other way around.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 14 '05 #11
In article <rn********************************@4ax.com>,
Alan Balmer <al******@spamcop.net> wrote:
Another such was named Plan - I remember a paper entitled "Why
Planning is Better Than Scheming." Or maybe the other way around.


I think you're thinking of "Why Conniving is Better than Planning":

ftp://publications.ai.mit.edu/ai-pub...499/AIM-255.ps

though I suppose there may have been a similarly named paper about
Scheme.

Scheme has been standardized by the IEEE. See:

http://www.cs.indiana.edu/scheme-rep...standards.html

-- Richard
Nov 14 '05 #12
Derrick Coetzee wrote:

pete wrote:
struct generic_node {
data the_data;
struct generic_node *next;
};

... but

struct generic_node {
void *data;
struct generic_node *next;
};

is really more generic.


Neither is typesafe,
but the first has the notable advantage of internal
storage, which for the small data the author considers is quite a
significant advantage in space overhead (especially with your typical
high-overhead memory allocator), as well as having cache benefits and
saving lots of dereferences.

It's also relatively simple to have a linked list datatype generic to
all data types and also using internal storage (and typesafe too), by
using macro-generated inline functions as an interface to a library of
linked list functions parameterized by data size.


The void *data; is handy for lists of lists.
Then you can use the same functions on different kinds of lists
in the same program.

--
pete
Nov 14 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Skywise | last post by:
I am fairly new to linked lists. I am trying to write a class using linked lists. It seems to work fine, but I need to know if I have any resource leaks in it because I plan on using this class...
5
by: Susanne Strege | last post by:
Hello... I'm wondering if it is possible to perform a CRC or Checksum on the data contained in a simple Linked List that uses pointers to nodes???
1
by: Booser | last post by:
// Merge sort using circular linked list // By Jason Hall <booser108@yahoo.com> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> //#define debug
7
by: Kieran Simkin | last post by:
Hi all, I'm having some trouble with a linked list function and was wondering if anyone could shed any light on it. Basically I have a singly-linked list which stores pid numbers of a process's...
57
by: Xarky | last post by:
Hi, I am writing a linked list in the following way. struct list { struct list *next; char *mybuff; };
4
by: MJ | last post by:
Hi I have written a prog for reversing a linked list I have used globle pointer Can any one tell me how I can modify this prog so that I dont have to use extra pointer Head1. When I reverse a LL...
2
by: tuan_vandyk | last post by:
Hi I desperately need help with my project. Theoretically everything should work bu it just isn't. Please email me for a copy of the project's source code. It was made in Turbo C++ 5. Please if...
23
by: Just Another Victim of the Ambient Morality | last post by:
I'm looking for a linked list implementation. Something iterable with constant time insertion anywhere in the list. I was wondering if deque() is the class to use or if there's something else. ...
11
by: Scott Stark | last post by:
Hello, The code below represents a singly-linked list that accepts any type of object. You can see I'm represting the Data variable a System.Object. How would I update this code to use...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.