线性表(Linear List)是由n(n≥0)个数据元素(结点)a[0],a[1],a[2]…,a[n-1]组成的有限序列spa
其中:指针
数据元素的个数n定义为表的长度 = "list".length() ("list".length() = 0(表里没有一个元素)时称为空表)code
将非空的线性表(n>=0)记做:(a[0],a[1],a[2],…,a[n-1])排序
数据元素a[i](0≤i≤n-1)只是个抽象符号,其具体含义在不一样状况下能够不一样 内存
线性链表:线性表的链式存储结构的特色是用一组任意的存储单元存储线性表的数据元素(这些存储单元能够是连续的,也能够是不连续的)。所以,为了表示每一个数据元素ai来讲,除了存储其自己的信息以外,还须要存储一个指示其直接后继的信息(即直接后继的存储位置)。it
节点,包括两个域:数据域,指针域。链表有不少种不一样的类型:单向链表,双向链表以及循环链表。io
头指针:单链表的头指针指向头结点。List
头结点:有时,咱们在单链表的第一个节点以前附设一个节点,称之为头结点。循环
头结点的指针域存储指向第一个节点的指针。若线性表为空,则头节点的指针域为空。im
如图所示
单链表的结构体定义
typedef struct Node { ElemType data; //数据域 struct Node *next; //指针域 }Node,*LinkList;
单链表的C实现:
#include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 #define SWAP(x,y) {t=x,x=y,y=t;} typedef int ElemType; typedef int Status; typedef struct LNode //线性表的单链表存储结构 { int data; //数据域 struct LNode *next; //指针域 }LNode,*LinkList; //这里的LNode实际上就是struct LNode的别名,同时LinkList是指针类型的,指向LNode //箭头运算符是二院操做符,其左边操做数必须是指针类型 Status Create_LinkList_Head(LinkList *L,int n) { int i; LinkList p; *L=(LinkList)malloc(sizeof(LNode)); (*L)->next=NULL; //先创建一个带有头结点的单链表 for(i=0 ; i<n ; i++) { if(!(p=(LinkList)malloc(sizeof(LNode)))) { printf("内存分配失败!"); exit(OVERFLOW); } printf("%d\n",p->data); printf("%x\n",p->data); scanf("%d",&(p->data)); printf("插入数据成功\n"); ////插入到表头。能够画图演示连接的过程 p->next=(*L)->next; //断开头结点和第一个节点间的链接。把当前第一个节点的地址赋给新节点的指针域。 (*L)->next=p;//同时头结点的指针域指向新节点 } printf("ok"); return OK; } Status Create_LinkList_Tail(LinkList *L,int n) { LinkList r,s; *L=(LinkList)malloc(sizeof(LNode)); //新建一个节点 r=*L; int i; for(i=0 ; i<n ; i++) { if(!(s=(LinkList)malloc(sizeof(LNode)))) { printf("内存分配失败"); exit(OVERFLOW); } scanf("%d",&(s->data)); r->next=s; //新的节点s被连接到上一个节点的指针域 r=s; //把节点s插入到尾部 } r->next=NULL; //当前链表结束 return OK; } Status Insert_LinkList(LinkList L,int i,ElemType e)//插入节点 { int j=0; LinkList p=L,s; while(j<i-1 && p) { p=p->next; j++; } if(!p || j>i-1) return ERROR; if(!(s=(LinkList)malloc(sizeof(LNode)))) { printf("内存分配失败"); exit(OVERFLOW); } s->data=e; s->next=p->next; p->next=s; return OK; } Status Delete_LinkList(LinkList L,int i,ElemType *e)//删除节点 { int j=0; LinkList p=L->next,q; while(j<i-1 && p) { p=p->next; j++; } if(!p || j>i-1) return ERROR; q=p->next; *e=q->data; p->next=q->next; free(q); return OK; } Status GetElem_LinkList(LinkList L,int i,ElemType *e)//获得指定的节点元素 { int j; LinkList p; j=1,p=L->next; while(j<i && p) { p=p->next; j++; } if(!p || j>i) return ERROR; *e=p->data; return OK; } Status Print_LinkList(LinkList L)//打印链表 { LinkList p=L->next; while(p) { printf("%d ",p->data); p=p->next; } printf("\n"); return OK; } int LinkList_Length(LinkList L)//获取链表的长度 { int len=0; LinkList p=L->next; while(p) { len++; p=p->next; } printf("length ok"); return len; } Status Destory_LinkList(LinkList head)//销毁链表 { LinkList p = head; while(head!=NULL) { head = head->next; free(p); p = head; } return OK; } Status Sort_LinkList(LinkList L)//排序 { LinkList La,Lb; ElemType t; La=L->next; Lb=La->next; while(Lb) { if(La->data>Lb->data) { SWAP(La->data,Lb->data); } Lb = Lb->next; if(!Lb) { La = La->next; Lb = La->next; } } return OK; } int main() { int n,ch,pos; ElemType insert; LinkList L=NULL; printf("请输入你要输入元素的个数\n"); scanf("%d",&n); printf("输入1,选择头插法(顺序),输入2,选择尾插法(逆序)\n"); scanf("%d",&ch); if(ch!=1 && ch!=2) { printf("输入错误,请从新输入"); scanf("%d",&ch); } if(ch==1) { printf("请输入%d个元素\n",n); Create_LinkList_Head(&L,n); } else if(ch==2) { printf("请输入%d个元素\n",n); Create_LinkList_Tail(&L,n); } printf("lyx"); printf("链表的长度为%d\n",LinkList_Length(L)); printf("打印链表==>\n"); Print_LinkList(L); printf("请输入你要插入的数据和位置\n"); scanf("%d%d",&insert,&pos); Insert_LinkList(L,pos,insert); int dl; printf("删除链表中的元素\n"); Delete_LinkList(L,3,&dl); Print_LinkList(L); int e; GetElem_LinkList(L,3,&e); printf("第三个节点的数据域是%d\n",e); printf("链表排序\n"); Sort_LinkList(L); Print_LinkList(L); printf("销毁链表\n"); Destory_LinkList(L); return 0; }
====END====