单链表
将线性表L=(a0,a1,a2,…a(n-1))中各元素分布在存储器的不同存储块,称为结点。通过地址或指针建立元素之间的联系。
data | next |
---|
结点的data域存放数据元素ai,而next域是一个指针,指向ai的直接后继==a(i+1)==所在的结点。
设p指针指向链表中结点ai
p->data表示获取ai,p->next->data表示获取a(i+1)
若p的值为NULL,则它不指向任何结点,此时取p->data以及p->next都是错误的。
模块呈现
typedef int data_t
typedef struct node{
data_t data; //结点数据域
struct node *next;//结点的指针域
}listnode, *linklist;
listnode A;
linklist p = &A;//结点变量的内存放在栈上
//会随函数结束销毁,有局限性
A.data = value;//访问成员
linklist p;//放堆上,动态存储(优)
p = (linklist)malloc(sizeof(listnode));//malloc开辟空间,结束后要free
p->data = value;//访问成员
代码
linklist.h文件
typedef int data_t;
typedef struct node {
data_t data;
struct node *next;
}listnode, *linklist;
linklist list_create();
int list_tail_insert(linklist H, data_t value);//head
linklist list_get(linklist H, int pos);
int list_insert(linklist H, data_t value, int pos);
int list_delete(linklist H, int pos);
int list_show(linklist H);
linklist list_free(linklist H);
int list_reverse(linklist H);//反转
linklist list_adjmax(linklist H, data_t *value);//相邻两元素的和作为参考来比较,和最大时输出该两元素的前者
int list_merge(linklist H1, linklist H2);
linklist list_sort(linklist H);
linklist.c文件
#include <stdio.h>
#include <stdlib.h>
#include "linklist.h"
linklist list_create()
{
linklist H;
H = (linklist)malloc(sizeof(listnode));
if(H == NULL)
{
printf("malloc failed\n");
return H;
}
H->data = 0;
H->next = NULL;
return H;
}
int list_tail_insert(linklist H, data_t value)
{
//1 new code
linklist p;
linklist q;
if(H == NULL)
{
printf("H is NULL\n");
return -1;
}
if((p = (linklist)malloc(sizeof(listnode))) == NULL)
{
printf("malloc failed\n");
return -1;
}
p->data = value;
p->next = NULL;
//2 locate tail node
q = H;
while(q->next != NULL)
{
q = q->next;
}
//3 insert
q->next = p;
return 0;
}
linklist list_get(linklist H, int pos)
{
linklist p;
int i;
if(H == NULL)
{
printf("H is NULL\n");
return NULL;
}
if(pos == -1)
{
return H;
}
if(pos < -1)
{
printf("pos is invalid\n");
return NULL;
}
p = H;
i = -1;
while(i < pos)
{
p = p->next;
if(p == NULL)
{
printf("pos is invalid\n");
return NULL;
}
i++;
}
return p;
}
int list_insert(linklist H, data_t value, int pos)
{
linklist p;
linklist q;
if(H == NULL)
{
printf("H is NULL\n");
return -1;
}
//1 locate node p (pos-1)
p = list_get(H, pos-1);
if(p == NULL)
{
return -1;
}
//2 new node q
if((q = (linklist)malloc(sizeof(listnode))) == NULL)
{
printf("malloc failed\n");
return -1;
}
q->data = value;
q->next = NULL;
//3 insert
q->next = p->next;
p->next = q;
return 0;
}
int list_delete(linklist H, int pos)
{
linklist p;
linklist q;
if (H == NULL)
{
printf("H is NULL\n");
return -1;
}
p = list_get(H, pos-1);
if(p == NULL)
{
return -1;
}
if(p->next == NULL)
{
printf("delete pos is invalid\n");
return -1;
}
q = p->next;
p->next = q->next;
printf("free:%d\n", q->data);
free(q);
q = NULL;
return 0;
}
int list_show(linklist H)
{
linklist p;
if(H == NULL)
{
printf("H is NULL\n");
return -1;
}
p = H;
while(p->next !=NULL)
{
printf("%d ", p->next->data);
p = p->next;
}
puts("");
return 0;
}
linklist list_free(linklist H)
{
linklist p;
if(H == NULL)
return NULL;
p = H;
printf("free:");
while(H != NULL)
{
p = H;
printf("%d ", p->data);
free(p);
H = H->next;
}
puts("");
return NULL;
}
int list_reverse(linklist H)
{
linklist p;
linklist q;
if (H == NULL)
{
printf("H is NULL\n");
return -1;
}
if(H->next == NULL || H->next->next == NULL)
{
return 0;
}
p = H->next->next;
H->next->next = NULL;
while(p != NULL)
{
q = p;
p = p->next;
q->next = H->next;
H->next = q;
}
return 0;
}
linklist list_adjmax(linklist H, data_t *value)
{
linklist p;
linklist q;
linklist r;
data_t sum;
if(H == NULL)
{
printf("H is NULL\n");
return NULL;
}
if (H->next == NULL || H->next->next == NULL || H->next->next->next == NULL)
{
return H;
}
q = H->next;
p = H->next->next;//p = q->next;
r = q;
sum = q->data + p->data;
while(p->next != NULL)
{
p = p->next;
q = q->next;
if(sum < q->data + p->data)
{
sum = q->data + p->data;
r = q;
}
}
*value = sum;
return r;
}
int list_merge(linklist H1, linklist H2)
{
linklist p,q,r;
if(H1 == NULL || H2 == NULL)
{
printf("H1||H2 is NULL\n");
return -1;
}
p = H1->next;
q = H2->next;
r = H1;
H1->next = NULL;
H2->next = NULL;
while(p && q)
{
if(p->data <= q->data)
{
r->next = p;
p = p->next;
r = r->next;
r->next = NULL;
}
else
{
r->next = q;
q = q->next;
r = r->next;
r->next = NULL;
}
}
if(p == NULL)
{
r->next = q;
}
else
{
r->next = p;
}
return 0;
}
linklist list_sort(linklist H)
{
linklist p;
linklist q;
linklist r;
data_t i;
data_t j;
if(H == NULL)
{
printf("H is NULL\n");
return NULL;
}
if (H->next == NULL || H->next->next == NULL)
{
return H;
}
q = H->next;
p = H->next->next;//p = q->next;
r = q;
for(j=4; j>0; j--)
{
while(p->next != NULL)
{
p = p->next;
q = q->next;
if(q->data > p->data)
{
i = q->data;
q->data = p->data;
p->data = i;
}
else
{
i = p->data;
p->data = q->data;
q->data = i;
}
}
p = H->next->next;
q = H->next;
r = q;
}
return r;
}
test.c文件
#include <stdio.h>
#include <stdlib.h>
#include "linklist.h"
void get();
void insert();
void delete();
void reverse();
void adjmax();
void merge();
int main(int argc, const char *argv[])
{
linklist H;
int value;
H = list_create();
if(H == NULL){
return -1;
}
printf("input:");
while(1){
scanf("%d", &value);
if(value == -1)
break;
list_tail_insert(H, value);
printf("input:");
}
list_show(H);
list_sort(H);
list_show(H);
list_free(H);
return 0;
}
void get(){
linklist H;
int value;
linklist p;
H = list_create();
if(H == NULL){
return -1;
}
printf("input:");
while(1){
scanf("%d", &value);
if(value == -1)
break;
list_tail_insert(H, value);
printf("input:");
}
p = list_get(H, 4);//1 3 5 7
if(p != NULL)
printf("value=%d\n", p->data);
return 0;
}
void insert(){
linklist H;
int value;
H = list_create();
if(H == NULL){
return -1;
}
printf("input:");
while(1){
scanf("%d", &value);
if(value == -1)
break;
list_tail_insert(H, value);
printf("input:");
}
list_show(H);
list_insert(H, 100, 4);
list_show(H);
return 0;
}
void delete(){
linklist H;
int value;
H = list_create();
if(H == NULL){
return -1;
}
printf("input:");
while(1){
scanf("%d", &value);
if(value == -1)
break;
list_tail_insert(H, value);
printf("input:");
}
list_show(H);
printf("H=%p\n", H);
H = list_free(H);
printf("H=%p\n", H);
list_delete(H, -4);
list_show(H);
list_free(H);
return 0;
}
void reverse(){
linklist H;
int value;
H = list_create();
if(H == NULL){
return -1;
}
printf("input:");
while(1){
scanf("%d", &value);
if(value == -1)
break;
list_tail_insert(H, value);
printf("input:");
}
list_show(H);
list_reverse(H);
list_show(H);
list_free(H);
return 0;
}
//相邻两元素的和作为参考来比较,和最大时输出该两元素的前者
void adjmax(){
linklist H;
linklist r;
int value;
int sum;
H = list_create();
if(H == NULL){
return -1;
}
printf("input:");
while(1){
scanf("%d", &value);
if(value == -1)
break;
list_tail_insert(H, value);
printf("input:");
}
list_show(H);
r = list_adjmax(H, &sum);
if (r != NULL && r != H){
printf("data=%d\n, sum=%d\n", r->data, sum);
}
list_show(H);
list_free(H);
return 0;
}
void merge(){
linklist H1,H2;
int a[]={1,40,6,8,10};
int b[]={20,4,16,18,30};
int i;
H1 = list_create();
if(H1 == NULL){
return -1;
}
H2 = list_create();
if(H2 == NULL){
return -1;
}
for(i = 0; i< sizeof(a)/sizeof(int); i++){
list_tail_insert(H1, a[i]);
}
for(i = 0; i< sizeof(b)/sizeof(int); i++){
list_tail_insert(H2, b[i]);
}
list_show(H1);
list_show(H2);
list_merge(H1, H2);
printf("merge:\n");
list_show(H1);
list_show(H2);
list_free(H1);
list_free(H2);
return 0;
}