线性表的链式存储(单链表)C语言实现
2014-04-17 20:11
645 查看
在顺序表中,我们用一组地址连续的存储单元来依次存放线性表的结点,因此结点的逻辑次序和物理次序是一致的。而链表不一样,链表使用一组任意的存储单元来存放线性表的结点,这组存储单元既可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任何位置上。因此,链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储其后继结点的地址信息。
#include <stdio.h> #include <stdlib.h> typedef int datatype; typedef struct node { datatype data; struct node *next; }linklist; /*头插法建立单链表,逐个输入字符,以“$”为结束符,返回单链表头指针*/ linklist *CreateListBefore(){ linklist *head,*s; char ch; ch = getchar(); while (ch != '$') { s =(linklist*) malloc(sizeof(linklist)); s->data = ch; s->next = head; head = s; ch = getchar(); } return head; } /*尾插法建立单链表,返回表头指针,不带头结点*/ linklist* CreatListTail() { char ch; linklist *head,*s,*rear; head = NULL; /*链表初值为空*/ rear = NULL; /*尾指针初值为空*/ ch = getchar(); /*读入第一个结点值*/ while (ch != '$') { s = (linklist*)malloc(sizeof(linklist)); s ->data = ch; if (head == NULL) { head = s; /*新结点*s插入空表*/ }else { rear->next = s; /*非空表,新结点*s插入到尾结点*r之后*/ } rear = s; /*尾指针*r指向新的表尾*/ } if (rear != NULL) { rear ->next = NULL; /*对非空表,将尾结点的指针域置空*/ } return head; } /*尾插法建立单链表,返回表头指针,带头结点*/ linklist *CreatListTailOne(){ char ch; linklist *head,*s,*rear; head = (linklist*)malloc(sizeof(linklist)); /*生成头结点*/ rear = head; /*尾指针初值指向头节点*/ ch = getchar(); /*读入第一个结点的值*/ while (ch != '$') { s = (linklist*)malloc(sizeof(linklist));/*生成新的结点*s*/ s->data = ch; rear->next = s; /*新结点插入表尾*/ rear = s; /*尾指针指向新的表尾*/ ch = getchar(); /*读入下一个结点的值*/ } rear ->next = NULL; return head; /*返回表头指针*/ } /*查找运算,按序号查找*/ linklist *Get(linklist *head,int i){ int j; linklist *temp; temp = head; /*从头开始扫描*/ j = 0; while ((temp ->next != NULL) && (j < i)) { temp = temp ->next; /*扫描下一个结点* 4000 / j ++; /*已扫描结点计数器*/ } if (i == j) /*找到第i个结点*/ { return temp; }else { return NULL; /*找不到,i≤0,或i>n*/ } } /*查找运算,按值查找*/ linklist *Loacate(linklist *head,datatype key){ linklist *temp; temp = head ->next;/*从开始结点开始比较*/ while (temp != NULL) { if (temp ->data != key) { temp = temp->next; /*没有找到继续循环*/ }else { break; /*找到结点key,退出循环*/ } } return temp; } /*插入运算,后插操作,将值为x的新结点插入到*location之后*/ void InsertAfter(linklist *Loacation,datatype x){ linklist *temp; temp = (linklist*)malloc(sizeof(linklist)); temp ->data = x; temp ->next = Loacation->next; Loacation ->next = temp; } /*前插操作*/ void InsertBefore(linklist *Location,datatype x){ linklist *temp =(linklist*)malloc(sizeof(linklist)); temp->data = Location->data; temp->next = Location->next; Location ->data = x; Location ->next = temp; } /*删除操作,*/ void DeleteAferter(linklist *Loaction){ linklist *temp; temp = Loaction->next; Loaction->next = temp->next; free(temp); }
相关文章推荐
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构揭秘一
- 关于C语言中参数的传值问题
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- 探讨C语言的那些小秘密之断言
- 深入探讨C语言中局部变量与全局变量在内存中的存放位置
- 基于C语言fflush()函数的使用详解
- 关于C语言除0引发的思考
- 深入分析C中不安全的sprintf与strcpy
- 探讨register关键字在c语言和c++中的差异
- C中实现矩阵乘法的一种高效的方法
- c语言printf函数的使用详解
- C语言学籍管理系统源代码
- 浅析C语言中的sizeof
- c语言内存泄露示例解析
- 浅析C语言位域和位段
- 解析C语言中位字段内存分配的问题
- 学生成绩管理系统C语言代码实现
- 基于C语言sprintf函数的深入理解