c语言实现一个单向链表,C语言实现一个简单的单向链表list

/*

* list.c

*        Generic linked list implementation.

*        cheungmine

*      Sep. 22, 2007.  All rights reserved.

*/

#include

"

list.h

"

/*

Appends a node to a list

*/

void

list_append_node(list_t

*

in_list, listnode_t

*

node)

{

node

->

next

=

NULL;

if

(in_list

->

head)

{

in_list

->

tail

->

next

=

node;

in_list

->

tail

=

node;

}

else

in_list

->

head

=

in_list

->

tail

=

node;

in_list

->

size

++

;

}

/*

Removes the first node from a list and returns it

*/

listnode_t

*

list_remove_head(list_t

*

in_list)

{

listnode_t

*

node

=

NULL;

if

(in_list

->

head)

{

node

=

in_list

->

head;

in_list

->

head

=

in_list

->

head

->

next;

if

(in_list

->

head

==

NULL)

in_list

->

tail

=

NULL;

node

->

next

=

NULL;

in_list

->

size

--

;

}

assert(in_list

->

size

>=

0

);

return

node;

}

/*

Removes all nodes but for list itself

*/

void

list_remove_all(list_t

*

in_list, pfcb_list_node_free pf)

{

listnode_t

*

node;

while

((node

=

list_remove_head(in_list))){

if

(pf) (

*

pf)(node);

free(node);

}

assert (in_list

->

size

==

0

);

}

/*

Returns a copy of a list_t from heap

*/

list_t

*

list_copy(list_t list)

{

list_t

*

newlist

=

(list_t

*

)malloc (

sizeof

(list_t));

*

newlist

=

list;

return

newlist;

}

/*

Concatenates two lists into first list

*/

void

list_concat(list_t

*

first, list_t

*

second)

{

if

(first

->

head)

{

if

(second

->

head)

{

first

->

tail

->

next

=

second

->

head;

first

->

tail

=

second

->

tail;

}

}

else

*

first

=

*

second;

second

->

head

=

second

->

tail

=

NULL;

first

->

size

+=

second

->

size;

}

/*

Allocates a new listnode_t from heap

*/

listnode_t

*

list_node_create(

void

*

data)

{

listnode_t

*

node

=

(listnode_t

*

)malloc (

sizeof

(listnode_t));

node

->

next

=

NULL;

node

->

data

=

data;

return

node;

}

listnode_t

*

list_key_create(

long

key)

{

listnode_t

*

node

=

(listnode_t

*

)malloc (

sizeof

(listnode_t));

node

->

next

=

NULL;

node

->

key

=

key;

return

node;

}

/*

Allocates a empty list_t from heap

*/

list_t

*

list_create()

{

list_t

*

list

=

(list_t

*

)malloc (

sizeof

(list_t));

list

->

size

=

0

;

list

->

head

=

list

->

tail

=

NULL;

return

list;

}

/*

Frees a empty list_t from heap

*/

void

list_destroy(list_t

*

in_list, pfcb_list_node_free  pf)

{

list_remove_all(in_list, pf);

free(in_list);

}

/*

Gets count of nodes in the list

*/

size_t

list_size(

const

list_t

*

in_list)

{

return

in_list

->

size;

}

/*

Gets node by index 0-based. 0 is head

*/

listnode_t

*

list_node_at(

const

list_t

*

in_list,

int

index)

{

int

i

=

0

;

listnode_t

*

node

=

in_list

->

head;

assert(index

>=

0

&&

index

<

(

int

)in_list

->

size);

while

(i

<

index)

{

node

=

node

->

next;

i

++

;

}

return

node;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设我们有两个单向链表A和B,它们分别表示两个集合。现在我们要求出集合A与集合B的差集,也就是只在A中出现而不在B中出现的元素。 我们可以遍历链表A,对于每个节点,判断它是否在链表B中出现过。如果出现过,则将该节点从链表A中删除。最后返回链表A即可。 下面是C语言实现的代码: ``` #include <stdio.h> #include <stdlib.h> // 定义节点结构体 typedef struct node { int data; struct node* next; } Node; // 创建新节点 Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; return newNode; } // 添加节点到链表末尾 void append(Node** headRef, int data) { Node* newNode = createNode(data); if (*headRef == NULL) { *headRef = newNode; return; } Node* tail = *headRef; while (tail->next != NULL) { tail = tail->next; } tail->next = newNode; } // 从链表中删除给定节点 void deleteNode(Node** headRef, Node* nodeToDelete) { if (*headRef == NULL) { return; } if (*headRef == nodeToDelete) { *headRef = nodeToDelete->next; free(nodeToDelete); return; } Node* prev = *headRef; while (prev->next != NULL && prev->next != nodeToDelete) { prev = prev->next; } if (prev->next == NULL) { return; } prev->next = nodeToDelete->next; free(nodeToDelete); } // 从链表A中删除在B中出现过的节点 void subtract(Node** headA, Node* headB) { Node* currA = *headA; while (currA != NULL) { Node* currB = headB; while (currB != NULL && currB->data != currA->data) { currB = currB->next; } if (currB != NULL) { deleteNode(headA, currA); currA = *headA; } else { currA = currA->next; } } } // 打印链表 void printList(Node* head) { Node* curr = head; while (curr != NULL) { printf("%d ", curr->data); curr = curr->next; } printf("\n"); } int main() { // 创建链表A Node* headA = NULL; append(&headA, 1); append(&headA, 2); append(&headA, 3); append(&headA, 4); append(&headA, 5); // 创建链表B Node* headB = NULL; append(&headB, 3); append(&headB, 4); // 求差集 subtract(&headA, headB); // 打印结果 printList(headA); return 0; } ``` 上述代码中,我们定义了一个节点结构体,包含一个整型数据和一个指向下一个节点的指针。我们还定义了一些操作链表的函数,如创建新节点、添加节点到链表末尾、删除节点等。最后,我们在主函数中创建了两个链表A和B,然后调用subtract函数求它们的差集,最后打印结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值