您的位置:首页 > 理论基础 > 数据结构算法

C语言数据结构:单向链表

2016-03-13 10:17 561 查看
线性表是最常用且最简单的一种数据结构。一个线性表是多个数据元素的序列,数据元素的具体含义可以根据自己的情况实现,而一个数据元素又可以由若干个数据项组成。下面用单向链表的方式实现线性表,数据元素仅有一个int型变量和指向下一节点的数据指针。程序的功能有插入,删除,修改,判断相等的数据是否存在,计算链表长度,根据位置返回节点值,排序和就地逆置。

#include <stdio.h>
#include <stdlib.h>

typedef struct _listNode{
int value;
struct _listNode * next;
}listNode, *pListNode;

pListNode List_create(int);

void List_destroy(pListNode head);

int List_getListLength(pListNode head);

int List_getNode(pListNode head, int pos, pListNode myNode);
// 0 presents no node at pos

int List_isExisting(pListNode head, pListNode myNode);
// 0 presents not exist, positive number is the position of the same-value node

pListNode List_insert(pListNode head, int pos, pListNode myNode);
// insert node at pos

pListNode List_delete(pListNode head, int pos, pListNode myNode);

void List_union(pListNode head1, pListNode head2);
// head1 is the new list

void List_modify(pListNode head, int pos, pListNode myNode);
// replace node contents at pos with myNode

pListNode List_ascendingSort(pListNode head);

pListNode List_localReverse(pListNode head);

void List_displayAll(pListNode head);

int main()
{
// these are test nodes
pListNode insert0 = List_create(0);
pListNode insert_1 = List_create(-1);
pListNode insert2 = List_create(2);
pListNode insert9 = List_create(9);

// head node
pListNode head = List_create(5);
List_displayAll(head);

// test insert operation
// insert before head
head = List_insert(head, 1, insert0);
printf("insert 0 before head.\n");
List_displayAll(head);
// insert between
head = List_insert(head, 2, insert_1);
printf("insert -1 at pos 2.\n");
List_displayAll(head);
// insert at tail
head = List_insert(head, 4, insert2);
printf("insert 2 at tail.\n");
List_displayAll(head);
head = List_insert(head, 4, insert9);
printf("insert 9 at pos 4.\n");
List_displayAll(head);
printf("\n");

// test get length operation
int len = List_getListLength(head);
printf("list length is: %d\n\n", len);

// test get node operation
pListNode temp = List_create(0);
printf("temp node value is: %d\n", temp->value);
List_getNode(head, 2, temp);
printf("after get node operation with pos 2, temp value is: %d\n", temp->value);
printf("before modify:\n");
List_displayAll(head);
printf("after modify with value %d at pos 1:\n", temp->value);
List_modify(head, 1, temp);
List_displayAll(head);
printf("\n");

// test is existing operation
int pos = List_isExisting(head, temp);
printf("is existing operation with value -1, result is: %d\n\n", pos);

// test delete operation
// delete head
head = List_delete(head, 1, temp);
printf("delete head.\n");
List_displayAll(head);
head = List_delete(head, 2, temp);
printf("delete node with pos 2.\n");
List_displayAll(head);
head = List_delete(head, List_getListLength(head), temp);
printf("delete tail.\n");
List_displayAll(head);
printf("\n");

// test union operation
pListNode head1 = List_create(10);
pListNode node = List_create(21);
head1 = List_insert(head1, 1, node);
printf("list 2 is: \n");
List_displayAll(head1);
printf("after union operation:\n");
List_union(head, head1);
List_displayAll(head);
printf("\n");

// test ascending operation
printf("after ascending operation:\n");
head = List_ascendingSort(head);
List_displayAll(head);
printf("\n");

// test local reverse operation
printf("after local reverse operation:\n");
head = List_localReverse(head);
List_displayAll(head);
printf("\n");

// test destroy operation
printf("after destroy operation:\n");
List_destroy(head);
printf("head value is invalid: %d\n\n", head->value);

system("pause");

return 0;
}

pListNode List_create(int value){
pListNode head = (pListNode)malloc(sizeof(listNode));
if(head == NULL){
printf("Have no space for head node.\n");
}
head->value = value;
head->next = NULL;
return head;
}

void List_destroy(pListNode head){
pListNode previous = NULL, current = head;
while(current != NULL){
previous = current;
current = current->next;
free(previous);
}

}

int List_getListLength(pListNode head){
int count = 0;
pListNode current = head;
while(current != NULL){
current = current->next;
count++;
}
return count;
}

// 0 presents no node at pos
int List_getNode(pListNode head, int pos, pListNode myNode){
if(pos < 1 || pos >= List_getListLength(head)){
printf("wrong position when get node.\n");
return 0;
}
int i = 1;
pListNode current = head;
while(i != pos){
current = current->next;
i++;
}
myNode->value = current->value;
myNode->next = NULL;
return 1;
}

// 0 presents not exist, positive number is the position of the same-value node
int List_isExisting(pListNode head, pListNode myNode){
int pos = 0, tag = 0;
pListNode current = head;
while(current != NULL){
pos++;
if(current->value == myNode->value){
tag = 1;
break;
}
current = current->next;
}
if(tag == 0){
pos = 0;
}
return pos;
}

// insert myNode at pos
pListNode List_insert(pListNode head, int pos, pListNode myNode){
if(pos < 1 || pos > List_getListLength(head)+1){
printf("wrong position when insert node.\n");
return head;
}
// insert before head
if(pos == 1){
myNode->next = head;
head = myNode;
return head;
}
// insert into the list
int i = 1;
pListNode previous = NULL, current = head;
while(current != NULL){
previous = current;
current = current->next;
i++;
if(i == pos){
break;
}
}
previous->next = myNode;
myNode->next = current;
return head;
}

pListNode List_delete(pListNode head, int pos, pListNode myNode){
if(pos < 1 || pos > List_getListLength(head)){
printf("wrong position when delete node.\n");
return head;
}
// judge if list is empty
if(head == NULL){
printf("list is empty, can't be delete.\n");
return head;
}
// delete head
pListNode current = head;
if(pos == 1){
head = head->next;
free(current);
return head;
}
// other situation
int i = 1;
for(i = 1; i < pos - 1; i++){
current = current->next;
}
pListNode deleteNode = current->next;
current->next = deleteNode->next;
myNode->value = deleteNode->value;
free(deleteNode);
return head;
}

// head1 is the new list
void List_union(pListNode head1, pListNode head2){
if(head1 == NULL){
printf("parameter is type of NULL, exit.\n");
return;
}
pListNode current = head1;
for(; current->next != NULL; current = current->next);
current->next = head2;
}

// replace node contents at pos with myNode
void List_modify(pListNode head, int pos, pListNode myNode){
if(head == NULL || myNode == NULL){
printf("head or node is type of NULL, exit.\n");
return;
}
if(pos < 1 || pos > List_getListLength(head)){
printf("wrong position when modify node.\n");
return;
}
int i = 1;
pListNode current = head;
for(; i < pos; i++, current = current->next);
current->value = myNode->value;
}

pListNode List_ascendingSort(pListNode head){
if(head == NULL){
printf("head is NULL.\n");
return head;
}
// bubble sort
pListNode current = head;
int temp = 0;
int i = 0, j = 0, k = List_getListLength(head);
for(i = 0; i < k; i++){
current = head;
for(j = 0; j < i; j++){
current = current->next;
}
for(j = i; j < k-1; j++){
if(current->value > current->next->value){
temp = current->value;
current->value = current->next->value;
current->next->value = temp;
}
current = current->next;
}
}
return head;
}

pListNode List_localReverse(pListNode head){
pListNode p = head, q = NULL;
head = NULL;
while(p){
q = p->next;
p->next = head;
head = p;
p = q;
}
return head;
}

void List_displayAll(pListNode head){
if(head == NULL){
printf("head is NULL, exit\n");
return;
}
pListNode current = head;
printf("list is: ");
for(; current != NULL; current = current->next){
printf("\t%d", current->value);
}
printf("\n");
}


下面是测试结果

list is:        5
insert 0 before head.
list is:        0       5
insert -1 at pos 2.
list is:        0       -1      5
insert 2 at tail.
list is:        0       -1      5       2
insert 9 at pos 4.
list is:        0       -1      5       9       2

list length is: 5

temp node value is: 0
after get node operation with pos 2, temp value is: -1
before modify:
list is:        0       -1      5       9       2
after modify with value -1 at pos 1:
list is:        -1      -1      5       9       2

is existing operation with value -1, result is: 1

delete head.
list is:        -1      5       9       2
delete node with pos 2.
list is:        -1      9       2
delete tail.
list is:        -1      9

list 2 is:
list is:        21      10
after union operation:
list is:        -1      9       21      10

after ascending operation:
list is:        -1      9       10      21

after local reverse operation:
list is:        21      10      9       -1

after destroy operation:
head value is invalid: 7025048
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: