preface:
In the last article, the blogger wrote about some simple operations of sequential strings. Strings, stacks and queues we have learned before have chain storage structures, because sequential storage is always limited, and chain storage does not need us to define the size, generate as much as we need, and release as little as we need. Indeed, chain storage has great advantages in storage, This article needs to be read in combination with the previous article, because there are many logic in it. Bloggers say that after reading the previous article, ha ha ha, steal a lazy. Let's learn next!!! 😁😁😁
Once a day, work hard!!
1. Understand the logic of chain string and the core code of chain string
The linked list storage structure of string is similar to the sequential storage structure, but also has the difference between compact and non compact storage structures. High efficiency of insertion and deletion; Low utilization of storage space;
Logic diagram of chain string establishment
Core code:
No hard code, just some basic code. As long as you learn the linked list well, there's no problem with this
typedef struct Node//structural morphology { char data; //Character field struct Node *next; //Pointer field, which stores the address of the next node }*LinkString;//Pointer structure type name LinkString s1;//Define string pointer s=(LinkString)malloc(sizeof(Node));//Allocate memory s->next=NULL;//The last one points to NULL q->data=p->data;//Assignment between string nodes free(q);//Release node
2. Initialization of chain string and some basic operations
The most basic initialization of chain string, judge the empty string and find the length.
LinkString CreateNullString() //Chain initialization operation { LinkString s;//Define the first node s=(LinkString)malloc(sizeof(Node));//Allocate memory if(s!=NULL) //Judge whether the allocation is successful. If successful, assign the pointer field NULL s->next=NULL; return s; } //Judge whether the chain string is empty int iEmpty(LinkString s)//Judge that the chain string s is empty { if(s->next==NULL)//The pointer field of s is null return 1; else return 0; } //Find the length of chain string int length(LinkString s)//Find the length of chain string { LinkString p; int n=0; p=s->next; while(p!=NULL)//Traversal chain { n++;//Cumulative Return p=p->next;//Downward displacement } return n;//Returns the value of the count variable } //Output operation void print(LinkString s)//Printout { LinkString p=s->next; while(p!=NULL) { printf("%c",p->data); p=p->next; } printf("\n"); }
3. Assignment of chain string
This assignment operation is equivalent to the tail interpolation of single linked list, which is not very difficult. The blogger also wrote detailed comments
void Stringassign(LinkString s,char t[])//Chain tail interpolation assignment operation { LinkString p,q,r; r=s; //r always represents the tail node (the last non empty node, not the last NULL node). q=s->next; int i; for(i=0;t[i]!='\0';i++)//Traverse the array we want to assign if(q!=NULL)//Judge whether this node of s is not empty {//Storage space is allocated to the head node during initialization or there are other situations q->data=t[i];//Assignment direct override r=q;//Record tail node q=q->next;//Point to a } else { p=(LinkString)malloc(sizeof(Node)); //Assign new node p->data=t[i];//assignment r->next=p;//The tail node connects the new node r=p;//Record new tail node } r->next=NULL;//The last node points to null while(q!=NULL) //Assuming that the s string is not an empty string, we should free up the original redundant space in S { p=p->next;//Point to next free(q);//release q=p;//Assign the unreleased to q } }
4. Copy chain string
The copy operation logic of chain string is consistent with that of sequential string. Those who do not understand can see the previous article of blogger. There's really nothing basically consistent in logic, so bloggers don't even want to draw a logic diagram. Bloggers will put an article below
void assign(LinkString s,LinkString t)//Chain string copy operation, copy the value of t string to s string { LinkString p,q,r,str; p=t->next; q=s->next; r=s; while(p!=NULL) //Traversal t string { if(q!=NULL)//Judge whether the s string is empty. If it is empty, it means that the s string has no memory { q->data=p->data;//copy r=q;//Used to record the value of each traversal of s string q=q->next;//s string moves back } else//The s string is empty. You need to divide the memory for s to save the value { str=(LinkString)malloc(sizeof(Node));//Create a new node to save the value str->data=p->data;//copy r->next=str;//The last one connects the new node r=str;//Change the direction of the tail pointer } p=p->next;//t walk back } while(q!=NULL)//If the s string is long enough and longer than the t string, it will be released { p=p->next; free(q);//Release redundant s nodes q=p; } r->next=NULL; }
5. Connection between chain strings
The logic of connection is the same as that of sequential string. You need to create a new string and then connect
//String connection operation void contact(LinkString s,LinkString s1,LinkString s2) { LinkString p,q,r,t; r=s; p=s1->next; q=s->next; while(p!=NULL)//Traverse S1 and assign it to s { if(q!=NULL)//Indicates that s has assigned nodes, which is similar to replication { q->data=p->data; q=q->next; r=q; } else { t=(LinkString)malloc(sizeof(Node)); //s has no allocated memory to allocate t->data=p->data; r->next=t; r=t; } p=p->next; } p=s2->next;//Reassign p to traverse s2 while(p!=NULL)//Ergodic s2 assignment { if(q!=NULL)//It's the same as s1 { q->data=p->data; q=q->next; r=q; } else { //String s did not allocate storage space, so it needs to apply for space t=(LinkString)malloc(sizeof(Node)); t->data=p->data; r->next=t; r=t; } p=p->next; } while(q!=NULL) //Traversal will clear the excess space of the string s, which may be very long { p=q->next; free(q); q=p; } r->next=NULL; //The last one points to NULL }
6. Chain type string obtaining substring operation
Use the diagram of sequence string to represent the logic. The logic is the same, but the assignments are different
//Intercept substring int substr(LinkString s,int i,int len,LinkString t) { LinkString p,q,r,u; if(i<=0 || i>length(s) || i+len-1>length(s) )//Judge the validity of i and len return 0; //The pointer points to the i-1 position of s int j,k; for(j=0,p=s;j<i;j++)//Traverse to the position where we want to take the substring p=p->next; for(k=0,r=t,q=t->next;k<len;k++) { if(q!=NULL)//Determine t whether memory is partitioned { q->data=p->data;//assignment r=q;//Used to record when the string t has no memory, r represents the tail q=q->next; } else { u=(LinkString)malloc(sizeof(Node));//Partition new memory u->data=p->data;//assignment r->next=u;//Connect new nodes r=u;//Change the position of the tail pointer } p=p->next;//Displacement of s string to the next } while(q!=NULL)//Traverse the redundant nodes of string t and release { p=q->next; free(q); q=p; } r->next=NULL; return 1; }
7. Insertion of chain string
Plum blossom twice. The insertion operation is represented by the diagram of the single linked list. It is really the same logic. There is no difference. The deletion is also the same logic.
//Insert operation int insert(LinkString s,int i,LinkString t)//S represents the string to be inserted, i represents where in the s string, and t represents the value to be inserted { LinkString p,q,r; if(i<=0 || i>length(s)+1)//Judge the validity of i return 0; //Point to position i-1 int j; for(j=0,p=s;j<i-1;j++)//Traverse s to the i th p=p->next; q=t->next; while(q!=NULL)//Traversal t insert string { r=(LinkString)malloc(sizeof(Node));//Allocation node r->data=q->data;//Save the value of t string, q is pointing to t r->next=p->next;//The new node establishes a connection to the next node of p, connects the node after p, and p represents the ith node p->next=r;//The i of s string is p, and the next of P is our insertion node to form a new chain q=q->next;//t string displacement to the next node p=r;//Represents the position of the displacement to the new node, and it is intended to insert a new value } return 1; }
8. Deletion of chain string
//Delete operation int deleteString(LinkString s,int i,int len){//s represents the string, i represents the starting position, and len represents the number after i LinkString p,q,r; if(i<=0 || i>length(s) || i+len-1>length(s) )//Consistent with the sequential string logic, you can see the previous article of the blogger return 0; int j; for(j=0,p=s;j<i-1;j++)//Traverse to the location we want to delete p=p->next; for(j=0;j<len;j++)//Traversal deletion is consistent with the deletion of the linked list. You can see the previous articles of the blogger { q=p->next;//Remember the last location deleted p->next=q->next;//Point the pointer field of the previous position to the next free(q); } return 1; }
9. Effect demonstration and overall code
Overall Code: (you can run directly)
#include <iostream> #include<stdio.h> #include<stdlib.h> typedef struct Node { char data; //Character field struct Node *next; //Pointer field, which stores the address of the next node }*LinkString; LinkString CreateNullString() //Chain initialization operation { LinkString s;//Define the first node s=(LinkString)malloc(sizeof(Node));//Allocate memory if(s!=NULL) //Judge whether the allocation is successful. If successful, assign the pointer field NULL s->next=NULL; return s; } int iEmpty(LinkString s)//Judge that the chain string s is empty { if(s->next==NULL)//The pointer field of s is null return 1; else return 0; } void Stringassign(LinkString s,char t[])//Chain tail interpolation assignment operation { LinkString p,q,r; r=s; //r always represents the tail node (the last non empty node, not the last NULL node). q=s->next; int i; for(i=0;t[i]!='\0';i++)//Traverse the array we want to assign if(q!=NULL)//Judge whether this node of s is not empty {//Storage space is allocated to the head node during initialization or there are other situations q->data=t[i];//Assignment direct override r=q;//Record tail node q=q->next;//Point to a } else { p=(LinkString)malloc(sizeof(Node)); //Assign new node p->data=t[i];//assignment r->next=p;//The tail node connects the new node r=p;//Record new tail node } r->next=NULL;//The last node points to null while(q!=NULL) //Assuming that the s string is not an empty string, we should free up the original redundant space in S { p=p->next;//Point to next free(q);//release q=p;//Assign the unreleased to q } } void assign(LinkString s,LinkString t)//Chain string copy operation, copy the value of t string to s string { LinkString p,q,r,str; p=t->next; q=s->next; r=s; while(p!=NULL) //Traversal t string { if(q!=NULL)//Judge whether the s string is empty. If it is empty, it means that the s string has no memory { q->data=p->data;//copy r=q;//Used to record the value of each traversal of s string q=q->next;//s string moves back } else//The s string is empty. You need to divide the memory for s to save the value { str=(LinkString)malloc(sizeof(Node));//Create a new node to save the value str->data=p->data;//copy r->next=str;//The last one connects the new node r=str;//Change the direction of the tail pointer } p=p->next;//t walk back } while(q!=NULL)//If the s string is long enough and longer than the t string, it will be released { p=p->next; free(q);//Release redundant s nodes q=p; } r->next=NULL; } int length(LinkString s)//Find the length of chain string { LinkString p; int n=0; p=s->next; while(p!=NULL)//Traversal chain { n++;//Cumulative Return p=p->next;//Downward displacement } return n;//Returns the value of the count variable } //String connection operation void contact(LinkString s,LinkString s1,LinkString s2) { LinkString p,q,r,t; r=s; p=s1->next; q=s->next; while(p!=NULL)//Traverse S1 and assign it to s { if(q!=NULL)//Indicates that s has assigned nodes, which is similar to replication { q->data=p->data; q=q->next; r=q; } else { t=(LinkString)malloc(sizeof(Node)); //s has no allocated memory to allocate t->data=p->data; r->next=t; r=t; } p=p->next; } p=s2->next;//Reassign p to traverse s2 while(p!=NULL)//Ergodic s2 assignment { if(q!=NULL)//It's the same as s1 { q->data=p->data; q=q->next; r=q; } else { //String s did not allocate storage space, so it needs to apply for space t=(LinkString)malloc(sizeof(Node)); t->data=p->data; r->next=t; r=t; } p=p->next; } while(q!=NULL) //Traversal will clear the excess space of the string s, which may be very long { p=q->next; free(q); q=p; } r->next=NULL; //The last one points to NULL } //Intercept substring int substr(LinkString s,int i,int len,LinkString t) { LinkString p,q,r,u; if(i<=0 || i>length(s) || i+len-1>length(s) ) return 0; //The pointer points to the i-1 position of s int j,k; for(j=0,p=s;j<i;j++) p=p->next; for(k=0,r=t,q=t->next;k<len;k++) { if(q!=NULL) { q->data=p->data; r=q; q=q->next; } else { u=(LinkString)malloc(sizeof(Node)); u->data=p->data; r->next=u; r=u; } p=p->next; } while(q!=NULL) { p=q->next; free(q); q=p; } r->next=NULL; return 1; } //Insert operation int insert(LinkString s,int i,LinkString t) { LinkString p,q,r; if(i<=0 || i>length(s)+1) return 0; //Point to position i-1 int j; for(j=0,p=s;j<i-1;j++) p=p->next; q=t->next; while(q!=NULL) { r=(LinkString)malloc(sizeof(Node)); r->data=q->data; r->next=p->next; p->next=r; q=q->next; p=r; } return 1; } //Delete operation int deleteString(LinkString s,int i,int len){ LinkString p,q,r; if(i<=0 || i>length(s) || i+len-1>length(s) ) return 0; int j; for(j=0,p=s;j<i-1;j++) p=p->next; for(j=0;j<len;j++) { q=p->next; p->next=q->next; free(q); } return 1; } //Printout void print(LinkString s) { LinkString p=s->next; while(p!=NULL) { printf("%c",p->data); p=p->next; } printf("\n"); } int main(int argc, char** argv) { LinkString s1; LinkString s2; LinkString s3; s1=CreateNullString(); s2=CreateNullString(); s3=CreateNullString(); char str[100]; printf("Please enter a string:\n"); gets(str); Stringassign(s1,str); printf("Chain string s1: "); print(s1); printf("Chain string s1 The length of the is:%d\n",length(s1)); assign(s2,s1); printf("Chain string s2: "); print(s2); printf("Chain string s2 Delete operation(The three characters in the second position are deleted:"); deleteString(s2,2,3); print(s2); printf("Chain operation connection s1 and s2 generate s3: "); contact(s3,s1,s2); print(s3); printf("Chain string insertion operation(from s1 Insert at position 6 of s3): "); insert(s1,6,s3); print(s1); printf("Function of chain string to intercept substring s2(intercept s3 String with length 4 at the fourth position of:"); substr(s3,4,4,s2); print(s2); return 0; }
Summary:
Chained strings are really not very difficult. They are all things we have learned before. The logic is basically the same. Now bloggers think why the linear list storage structure should be learned first, because the subsequent stacks, queues and strings are basically completed on the basis of the linked list. It is not very difficult. There are no technical problems. Next, I will learn arrays, Pay attention to the following articles. It's not easy to create, like, comment and collect!! ❤❤❤
Previous: Data structure upgraded learning, series (sequential string and algorithm)