(七)链表----非循环单链表常用算法实现

来源:互联网 发布:sql server between 编辑:程序博客网 时间:2024/06/11 22:03

1.链表的创建

# include <stdio.h># include <string.h># include <malloc.h>typedef struct Node{    int data;  // 数据域    struct Node * pNext; // 指针域 }NODE, *PNODE; // 创建一个非循环单链表PNODE create_list(void);int main(void){    PNODE pHead = NULL;// 创建一个非循环单链表,并将该链表的头节点地址赋值给    pHead = create_list();      traverse_list(pHead);    return 0;}PNODE create_list(void){// 链表的长度int len;int i;// 临时存放数据的变量int val;// 申请一个头节点的内存空间PNODE pHead = (PNODE)malloc(sizeof(NODE));if(NULL == pHead){    printf("分配失败");    exit(-1);}/*    声明一个临时节点变量pTail    并将这个被头节点赋值后的变量pTail的指针域置为NULL    假如只有一个节点,那么这个节点的指针域应该是为NULL的,    此时pTail就是这个唯一的节点*/PNODE pTail = pHead;pTail->pNext = NULL;

printf("请输入您要生成的链表的节点的个数:length = ");scanf("%d", len);for(i = 0; i < len; i++){    printf("请输入第%d个节点的值:", i+1);    scanf("%d", &val);    // 为输入的数据申请内存空间    PNODE pNew = (PNODE)malloc(sizeof(NODE));    if(NULL == pNew){        printf("分配失败");        exit(-1);    }    // 将输入的数据存入到这个数据域中    pNew->data = val;    // 将新的节点赋值给pTail    pTail->pNext = pNew;    // 将新的节点的指针域置为NULL    pNew->pNext = NULL;    // 将新的节点赋值给pTail节点    pTail = pNew;}return pHead;

}

2.链表的遍历

// 遍历比较简单void traver_list(PNODE pHead){    // 将头节点的指针域指向的地址赋值给p    PNODE p = pHead->pNext;    while(NULL != p){        // 只要p不为NULL,那么就输出;        printf("%d ", p->data);        // 输出完后将p重新指向下一个指针域的地址        p = p->pNext;    }    printf("\n");}

3.是否为空链表

bool is_empty(PNODE pHead){    // 如果头节点的指针域为NULL,那么这个链表肯定是空的     if(NULL == pHead->pNext){        return true;    }else{        return false;    }}

4.链表的长度

// 和遍历差不多int length_list(PNODE pHead){    PNODE p = pHead->pNext;    // 记录长度的变量    int length = 0;    while(NULL != p){        // 只要p不为NULL,那么就++        length++;        p = p->pNext;    }    return length;} 

5.排序

  链表和数组虽然有所区别,但是它们都是一种线性结构,所以在排序算法上是一样的,这牵扯到算法的广义和狭义之分以及泛型
  
  狭义算法:是数据存储方式的实现,具体到代码的每一步编写,与数据的存储方式密切相关
  广义算法:以什么样的方式来实现,并不一定要具体的代码的编写,与数据的存储方式无关
  泛型:以某种技术达到一种数据存储方式不同,但能够执行相同的操作。
  这里的泛型并不是Java中的泛型,Java的泛型只是一种对数据合法性的检查,(并且Java中的泛型是一种伪泛型,只在编译的时候进行检查,运行的时候就会被删除掉)

以冒泡排序为例:

1.数组的排序方式:

int temp = 0;for(int i = 0; i < length - 1; i++){    for(int j = i + 1; j < i; j++){        if(a[i] < a[j]){            temp = a[i];            a[i] = a[j];            a[j] = temp;        }    }}

2.链表的排序方式:

void sort_list(PNODE pHead){    int i, j, temp;    // 链表的长度,在此可使用之前的链表的长度函数    int len = length_list(pHead);    // 两个链表变量    // 这里假设p变量为a[i],q变量为a[j]    PNODE p, q;    // p = pHead->pNext就是将头节点的指针域的指向地址赋值给p    // 每次循环p重新赋值为p->pNext;    for(i = 0, p = pHead->pNext; i < len-1; i++, p=p->pNext){    // q = p->pNext 将p的下一节点赋值给q    // q = q->pNext 每次循环完,q也要进行重新赋值        for(j = i + 1, q = p->pNext; j < len; j++, q = q->pNext){            if(p->data > q->data){      // 类似于 a[i] > a[j}                 temp = p->data;         //        temp = a[i]                p->data = q->data;      //        a[i] = a[j]                q ->data = temp;        //        a[j] = temp;            }        }    }}

  
链表是离散的,并不是数组那样的连续空间,所以它们的算法肯定会存在差异,这是狭义上的算法的差异,但是它们又都是一种线性结构,那么在算法上是非常相似的,所以链表的排序算法可以和数组的算法一样,这是广义上的算法。而这之间使用的方式让它们的操作一样,这就叫泛型。

6.插入

/*     pHead:头节点    pos: 数据节点要插入的位置    val: 该节点的值    如果插入成功返回true,否则返回false*/bool insert_list(PNODE pHead, int pos, int val){    int i = 0;    PNODE p = pHead;    while(NULL != p && i < pos - 1){        p = p->pNext;        i++;    }    if(i > pos - 1 || NULL == p){        return false;    }    PNODE pNew = (PNODE)malloc(sizeof(NODE));    if(NULL == pNew){        printf("动态分配内存失败!\n");        exit(-1);    }    pNew->data = val;    PNODE q = p->pNext;    p->pNext = pNew;    pNew->pNext = q;    return true;}


  

7.删除

bool delete_list(PNODE pHead, int pos, int * pVal){    int i = 0;    PNODE p = pHead;    while(NULL != p->pNext && i < pos - 1){        p = p->pNext;        i++;     }    if(i > pos-1 || NULL == p->pNext){        return false;    }    PNODE q = p->pNext;    // 将删除的节点的数据存到pVal中 ,仅仅是为了知道删除了什么     *pVal = q->data;    // 删除p节点后面的节点    p->pNext = p->pNext->pNext;    // 释放掉删除的节点的内存     free(q);    // 将变量为NULL释放掉     q = NULL;    return true; } 
阅读全文
0 0
原创粉丝点击