数据结构与算法(Python语言描述)课件3
线性表的链式存储 用一组地址任意的存储单元存放线性表中的数据元素,结点动态生成,利用指示元素位置的指针表示逻辑关系 几种形式: 单链表、循环链表、双向链表、双向循环链表 链式存储 每个结点包括数据域和指向链表中下一个结点的指针。 单链表 a1 a2 a3 ∧ L 头结点 首元素结点 typedef struct LNode { ElemType data; // 数据域 struct LNode *next; // 指针域 } LNode, *LinkList; LinkList L; // L 为单链表的头指针 单链表的表示 void ListInit(LinkList &L){ //初始化 L=(LNode *)malloc(sizeof(LNode)); L->next=NULL; } 单链表的操作 L ? a1 a2 a5 ∧ L a3 a4 p=L->next; while(p!=NULL){ 第p指向的结点操作; p=p->next; //指针前行 } 单链表的遍历 a1 a2 a5 ∧ L a3 a4 p=L->next; j=1; //可替换为:p=L; j=0; while(p!=NULL && jnext; j++ } if (p!=NULL) 对第i个结点操作; else 第i个结点不存在; 确定链表中的第i个元素位置 Status GetElem_L(LinkList L, int i, ElemType &e){ // L是带头结点的链表的头指针,以e 返回第i 个元素 // 确定第i个元素的位置 p = L->next; j = 1; while (p && jnext; ++j; } if ( !p || j>i ) // 第i个元素不存在 return ERROR; e = p->data; //取得第i个元素 return OK; } 算法时间复杂度为:O(ListLength(L)) Status ListInsert_L(LinkList &L, int i, ElemType e){ // L 为带头结点的单链表的头指针,在第i 个结点之前插入元素e //确定第i-1个元素的位置 p = L; j = 0; while (p && j < i-1) { p = p->next; ++j; } if (!p || j > i-1) return ERROR; 生成结点插入在p之后; return OK; } 算法的时间复杂度为: O(ListLength(L)) // 生成新结点 s = (LinkNode *) malloc ( sizeof (LNode)); s->data = e; s->next = p->next; //先连后! p->next = s; //再改前! 生成结点插入在p之后 e ai-1 ai ai-1 s p q = p->next; p->next = q->next; e = q->data; free(q); 删除指针p指向的结点 ai-1 ai ai+1 ai-1 p q void ClearList(&L) { // 将单链表重新置为一个空表 while (L->next) { p=L->next; L->next=p->next; free(p); } } 算法时间复杂度:O(ListLength(L)) void CreateList_L(LinkList &L, int n) { // 逆序输入n 个数据元素,建立带头结点的单链表 // 先建立一个带头结点的单链表 L = (LinkList) malloc (sizeof (LNode)); L->next = NULL; for (i = n; i > 0; --i) { p = (LinkList) malloc (sizeof (LNode)); scanf(&p->data); // 输入元素值 p->next = L->next; L->next = p; // 插入L之后 } } 算法的时间复杂度为: O(Listlength(L)) 和单链表在搜索操作上的差别: 单链表:while ( p!=NULL ) {…} 循环链表:while ( p!=L ) {…} 循环链表 a1 a2 … ... an typedef